diff --git a/.forgejo/workflows/push.yaml b/.forgejo/workflows/push.yaml deleted file mode 100644 index 219205f..0000000 --- a/.forgejo/workflows/push.yaml +++ /dev/null @@ -1,190 +0,0 @@ -name: "BTClock CI" - -on: - push: - tags: - - "*" - workflow_dispatch: - -jobs: - build: - runs-on: docker - container: - image: ghcr.io/catthehacker/ubuntu:js-22.04 - permissions: - contents: write - checks: write - steps: - - uses: actions/checkout@v4 - with: - submodules: recursive - - uses: actions/setup-node@v4 - with: - node-version: lts/* - cache: yarn - cache-dependency-path: "**/yarn.lock" - - uses: actions/cache@v4 - with: - path: | - ~/.cache/pip - ~/.platformio/.cache - ~/data/node_modules - .pio - data/node_modules - key: ${{ runner.os }}-pio - - uses: actions/setup-python@v5 - with: - python-version: "3.9" - cache: "pip" - - name: Get current date - id: dateAndTime - shell: bash - run: echo "dateAndTime=$(date +'%Y-%m-%d-%H:%M')" >> $GITHUB_OUTPUT - - name: Install PlatformIO Core - shell: bash - run: pip install --upgrade platformio - - name: Run unit tests - shell: bash - run: mkdir -p junit-reports && pio test -e native_test_only --junit-output-path junit-reports/ - - name: Build BTClock firmware - shell: bash - run: pio run - - name: Build BTClock filesystem - shell: bash - run: pio run --target buildfs - - name: Copy bootloader to output folder - run: cp ~/.platformio/packages/framework-arduinoespressif32/tools/partitions/boot_app0.bin .pio - - name: Upload artifacts - uses: https://code.forgejo.org/forgejo/upload-artifact@v4 - with: - include-hidden-files: true - retention-days: 1 - name: prepared-outputs - path: .pio/**/*.bin - merge: - runs-on: docker - container: - image: ghcr.io/catthehacker/ubuntu:js-22.04 - permissions: - contents: write - checks: write - needs: build - continue-on-error: true - strategy: - matrix: - chip: - - name: lolin_s3_mini - version: esp32s3 - - name: btclock_rev_b - version: esp32s3 - - name: btclock_v8 - version: esp32s3 - epd_variant: [213epd, 29epd] - exclude: - - chip: { name: btclock_rev_b, version: esp32s3 } - epd_variant: 29epd - - chip: { name: btclock_v8, version: esp32s3 } - epd_variant: 29epd - steps: - - uses: https://code.forgejo.org/forgejo/download-artifact@v4 - with: - name: prepared-outputs - path: .pio - - name: Install esptools.py - run: pip install --upgrade esptool - - name: Create merged firmware binary - shell: bash - run: | - mkdir -p ${{ matrix.chip.name }}_${{ matrix.epd_variant }} - if [ "${{ matrix.chip.name }}" == "btclock_v8" ]; then - esptool.py --chip ${{ matrix.chip.version }} merge_bin \ - -o ${{ matrix.chip.name }}_${{ matrix.epd_variant }}/${{ matrix.chip.name }}_${{ matrix.epd_variant }}.bin \ - --flash_mode dio \ - --flash_freq 80m \ - --flash_size 16MB \ - 0x0000 .pio/build/${{ matrix.chip.name }}_${{ matrix.epd_variant }}/bootloader.bin \ - 0x8000 .pio/build/${{ matrix.chip.name }}_${{ matrix.epd_variant }}/partitions.bin \ - 0xe000 .pio/build/${{ matrix.chip.name }}_${{ matrix.epd_variant }}/ota_data_initial.bin \ - 0x10000 .pio/build/${{ matrix.chip.name }}_${{ matrix.epd_variant }}/firmware.bin \ - 0xDF0000 .pio/build/${{ matrix.chip.name }}_${{ matrix.epd_variant }}/littlefs_16MB.bin - elif [ "${{ matrix.chip.name }}" == "btclock_rev_b" ]; then - esptool.py --chip ${{ matrix.chip.version }} merge_bin \ - -o ${{ matrix.chip.name }}_${{ matrix.epd_variant }}/${{ matrix.chip.name }}_${{ matrix.epd_variant }}.bin \ - --flash_mode dio \ - --flash_freq 80m \ - --flash_size 8MB \ - 0x0000 .pio/build/${{ matrix.chip.name }}_${{ matrix.epd_variant }}/bootloader.bin \ - 0x8000 .pio/build/${{ matrix.chip.name }}_${{ matrix.epd_variant }}/partitions.bin \ - 0xe000 .pio/build/${{ matrix.chip.name }}_${{ matrix.epd_variant }}/ota_data_initial.bin \ - 0x10000 .pio/build/${{ matrix.chip.name }}_${{ matrix.epd_variant }}/firmware.bin \ - 0x6F0000 .pio/build/${{ matrix.chip.name }}_${{ matrix.epd_variant }}/littlefs_8MB.bin; - else - esptool.py --chip ${{ matrix.chip.version }} merge_bin \ - -o ${{ matrix.chip.name }}_${{ matrix.epd_variant }}/${{ matrix.chip.name }}_${{ matrix.epd_variant }}.bin \ - --flash_mode dio \ - 0x0000 .pio/build/${{ matrix.chip.name }}_${{ matrix.epd_variant }}/bootloader.bin \ - 0x8000 .pio/build/${{ matrix.chip.name }}_${{ matrix.epd_variant }}/partitions.bin \ - 0xe000 .pio/build/${{ matrix.chip.name }}_${{ matrix.epd_variant }}/ota_data_initial.bin \ - 0x10000 .pio/build/${{ matrix.chip.name }}_${{ matrix.epd_variant }}/firmware.bin \ - 0x380000 .pio/build/${{ matrix.chip.name }}_${{ matrix.epd_variant }}/littlefs_4MB.bin - # Adjust the offset for littlefs or other files as needed for the original case - fi - - - name: Create checksum for firmware - shell: bash - run: shasum -a 256 .pio/build/${{ matrix.chip.name }}_${{ matrix.epd_variant }}/firmware.bin | awk '{print $1}' > ${{ matrix.chip.name }}_${{ matrix.epd_variant }}/${{ matrix.chip.name }}_${{ matrix.epd_variant }}_firmware.bin.sha256 - - - name: Create checksum for merged binary - shell: bash - run: shasum -a 256 ${{ matrix.chip.name }}_${{ matrix.epd_variant }}/${{ matrix.chip.name }}_${{ matrix.epd_variant }}.bin | awk '{print $1}' > ${{ matrix.chip.name }}_${{ matrix.epd_variant }}/${{ matrix.chip.name }}_${{ matrix.epd_variant }}.bin.sha256 - - - name: Create checksum for littlefs partition - shell: bash - run: | - fs_file=$(find .pio/build/${{ matrix.chip.name }}_${{ matrix.epd_variant }} -name "littlefs*.bin") - echo $fs_file - fs_name=$(basename "$fs_file") - shasum -a 256 "$fs_file" | awk '{print $1}' > "${{ matrix.chip.name }}_${{ matrix.epd_variant }}/${fs_name}.sha256" - cat "${{ matrix.chip.name }}_${{ matrix.epd_variant }}/${fs_name}.sha256" - - name: Copy all artifacts to output folder - run: cp .pio/build/${{ matrix.chip.name }}_${{ matrix.epd_variant }}/*.bin .pio/boot_app0.bin ${{ matrix.chip.name }}_${{ matrix.epd_variant }} - - - name: Create OTA binary file - run: mv ${{ matrix.chip.name }}_${{ matrix.epd_variant }}/firmware.bin ${{ matrix.chip.name }}_${{ matrix.epd_variant }}/${{ matrix.chip.name }}_${{ matrix.epd_variant }}_firmware.bin - - name: Upload artifacts - uses: https://code.forgejo.org/forgejo/upload-artifact@v4 - with: - name: build-${{ matrix.chip.name }}-${{ matrix.epd_variant }} - path: | - ${{ matrix.chip.name }}_${{ matrix.epd_variant }}/*.bin - ${{ matrix.chip.name }}_${{ matrix.epd_variant }}/*.sha256 - release: - runs-on: docker - permissions: - contents: write - checks: write - needs: merge - steps: - - name: Download matrix outputs - uses: https://code.forgejo.org/forgejo/download-artifact@v4 - with: - pattern: build-* - merge-multiple: false - path: temp - - name: Copy files - run: | - mkdir -p release - find temp -type f \( -name "*.bin" -o -name "*.sha256" \) -exec cp -f {} release/ \; - - name: Create release - uses: https://code.forgejo.org/actions/forgejo-release@v2.4.0 - with: - url: "https://git.btclock.dev" - repo: "${{ github.repository }}" - direction: upload - tag: "${{ github.ref_name }}" - sha: "${{ github.sha }}" - release-dir: release - token: ${{ secrets.TOKEN }} - override: ${{ github.ref_type != 'tag' && github.ref_name != 'main' }} - prerelease: ${{ github.ref_type != 'tag' && github.ref_name != 'main' }} - release-notes-assistant: false diff --git a/.github/actions/install-build/action.yml b/.github/actions/install-build/action.yml index bb521cd..bf67cab 100644 --- a/.github/actions/install-build/action.yml +++ b/.github/actions/install-build/action.yml @@ -9,14 +9,14 @@ runs: node-version: lts/* cache: yarn cache-dependency-path: '**/yarn.lock' - - uses: actions/cache@v4 + - uses: actions/cache@v3 with: path: | ~/.cache/pip ~/.platformio/.cache ~/data/node_modules key: ${{ runner.os }}-pio - - uses: actions/setup-python@v5 + - uses: actions/setup-python@v4 with: python-version: '3.9' - name: Get current date diff --git a/.github/workflows/tagging.yml b/.github/workflows/tagging.yml index 8f64608..9d2a0c3 100644 --- a/.github/workflows/tagging.yml +++ b/.github/workflows/tagging.yml @@ -1,9 +1,9 @@ name: BTClock CI -on: +on: push: tags: - - "*" + - '*' jobs: build: @@ -22,7 +22,6 @@ jobs: - name: Upload artifacts uses: actions/upload-artifact@v4 with: - include-hidden-files: true retention-days: 1 name: prepared-outputs path: .pio/**/*.bin @@ -38,16 +37,7 @@ jobs: chip: - name: lolin_s3_mini version: esp32s3 - - name: btclock_rev_b - version: esp32s3 - - name: btclock_v8 - version: esp32s3 epd_variant: [213epd, 29epd] - exclude: - - chip: {name: btclock_rev_b, version: esp32s3} - epd_variant: 29epd - - chip: {name: btclock_v8, version: esp32s3} - epd_variant: 29epd steps: - uses: actions/download-artifact@v4 with: @@ -55,51 +45,16 @@ jobs: path: .pio - name: Install esptools.py run: pip install --upgrade esptool - # - name: Create merged firmware binary - # run: mkdir -p ${{ matrix.chip.name }}_${{ matrix.epd_variant }} && esptool.py --chip ${{ matrix.chip.version }} merge_bin -o ${{ matrix.chip.name }}_${{ matrix.epd_variant }}/${{ matrix.chip.name }}_${{ matrix.epd_variant }}.bin --flash_mode dio 0x0000 .pio/build/${{ matrix.chip.name }}_${{ matrix.epd_variant }}/bootloader.bin 0x8000 .pio/build/${{ matrix.chip.name }}_${{ matrix.epd_variant }}/partitions.bin 0xe000 .pio/boot_app0.bin 0x10000 .pio/build/${{ matrix.chip.name }}_${{ matrix.epd_variant }}/firmware.bin 0x369000 .pio/build/${{ matrix.chip.name }}_${{ matrix.epd_variant }}/littlefs.bin - - name: Create merged firmware binary - run: | - if [ "${{ matrix.chip.name }}" == "btclock_v8" ]; then - mkdir -p ${{ matrix.chip.name }}_${{ matrix.epd_variant }} && \ - esptool.py --chip ${{ matrix.chip.version }} merge_bin \ - -o ${{ matrix.chip.name }}_${{ matrix.epd_variant }}/${{ matrix.chip.name }}_${{ matrix.epd_variant }}.bin \ - --flash_mode dio \ - --flash_freq 80m \ - --flash_size 16MB \ - 0x0000 .pio/build/${{ matrix.chip.name }}_${{ matrix.epd_variant }}/bootloader.bin \ - 0x8000 .pio/build/${{ matrix.chip.name }}_${{ matrix.epd_variant }}/partitions.bin \ - 0xe000 .pio/build/${{ matrix.chip.name }}_${{ matrix.epd_variant }}/ota_data_initial.bin \ - 0x10000 .pio/build/${{ matrix.chip.name }}_${{ matrix.epd_variant }}/firmware.bin \ - 0x810000 .pio/build/${{ matrix.chip.name }}_${{ matrix.epd_variant }}/littlefs.bin; - else - # Original command for other cases - mkdir -p ${{ matrix.chip.name }}_${{ matrix.epd_variant }} && \ - esptool.py --chip ${{ matrix.chip.version }} merge_bin \ - -o ${{ matrix.chip.name }}_${{ matrix.epd_variant }}/${{ matrix.chip.name }}_${{ matrix.epd_variant }}.bin \ - --flash_mode dio \ - 0x0000 .pio/build/${{ matrix.chip.name }}_${{ matrix.epd_variant }}/bootloader.bin \ - 0x8000 .pio/build/${{ matrix.chip.name }}_${{ matrix.epd_variant }}/partitions.bin \ - 0xe000 .pio/build/${{ matrix.chip.name }}_${{ matrix.epd_variant }}/ota_data_initial.bin \ - 0x10000 .pio/build/${{ matrix.chip.name }}_${{ matrix.epd_variant }}/firmware.bin \ - 0x369000 .pio/build/${{ matrix.chip.name }}_${{ matrix.epd_variant }}/littlefs.bin - # Adjust the offset for littlefs or other files as needed for the original case - fi - - name: Create checksum for firmware - run: shasum -a 256 .pio/build/${{ matrix.chip.name }}_${{ matrix.epd_variant }}/firmware.bin | awk '{print $1}' > ${{ matrix.chip.name }}_${{ matrix.epd_variant }}/${{ matrix.chip.name }}_${{ matrix.epd_variant }}_firmware.bin.sha256 + - name: Create merged firmware binary + run: mkdir -p ${{ matrix.chip.name }}_${{ matrix.epd_variant }} && esptool.py --chip ${{ matrix.chip.version }} merge_bin -o ${{ matrix.chip.name }}_${{ matrix.epd_variant }}/${{ matrix.chip.name }}_${{ matrix.epd_variant }}.bin --flash_mode dio 0x0000 .pio/build/${{ matrix.chip.name }}_${{ matrix.epd_variant }}/bootloader.bin 0x8000 .pio/build/${{ matrix.chip.name }}_${{ matrix.epd_variant }}/partitions.bin 0xe000 .pio/boot_app0.bin 0x10000 .pio/build/${{ matrix.chip.name }}_${{ matrix.epd_variant }}/firmware.bin 0x369000 .pio/build/${{ matrix.chip.name }}_${{ matrix.epd_variant }}/littlefs.bin - name: Create checksum for merged binary - run: shasum -a 256 ${{ matrix.chip.name }}_${{ matrix.epd_variant }}/${{ matrix.chip.name }}_${{ matrix.epd_variant }}.bin | awk '{print $1}' > ${{ matrix.chip.name }}_${{ matrix.epd_variant }}/${{ matrix.chip.name }}_${{ matrix.epd_variant }}.bin.sha256 - - - name: Create checksum for littlefs partition - run: shasum -a 256 .pio/build/${{ matrix.chip.name }}_${{ matrix.epd_variant }}/littlefs.bin | awk '{print $1}' > ${{ matrix.chip.name }}_${{ matrix.epd_variant }}/littlefs.bin.sha256 + run: shasum -a 256 ${{ matrix.chip.name }}_${{ matrix.epd_variant }}/${{ matrix.chip.name }}_${{ matrix.epd_variant }}.bin | awk '{print $1}' > ${{ matrix.chip.name }}_${{ matrix.epd_variant }}/${{ matrix.chip.name }}_${{ matrix.epd_variant }}.sha256 - name: Copy all artifacts to output folder run: cp .pio/build/${{ matrix.chip.name }}_${{ matrix.epd_variant }}/*.bin .pio/boot_app0.bin ${{ matrix.chip.name }}_${{ matrix.epd_variant }} - - name: Create OTA binary file - run: mv ${{ matrix.chip.name }}_${{ matrix.epd_variant }}/firmware.bin ${{ matrix.chip.name }}_${{ matrix.epd_variant }}/${{ matrix.chip.name }}_${{ matrix.epd_variant }}_firmware.bin - - name: Upload artifacts uses: actions/upload-artifact@v4 with: @@ -121,10 +76,10 @@ jobs: merge-multiple: false - name: Write commit hash to file run: echo $GITHUB_SHA > commit.txt - + - name: Write build date to file run: echo "$(date -u +'%Y-%m-%dT%H:%M:%SZ')" > date.txt - + - name: Create release uses: ncipollo/release-action@v1 with: @@ -147,8 +102,8 @@ jobs: with: source-directory: . target-directory: firmware_v3/ - destination-github-username: "btclock" - destination-repository-name: "web-flasher" - target-branch: main + destination-github-username: 'btclock' + destination-repository-name: 'web-flasher' + target-branch: btclock user-name: ${{github.actor}} - user-email: ${{github.actor}}@users.noreply.github.com + user-email: ${{github.actor}}@users.noreply.github.com \ No newline at end of file diff --git a/.gitignore b/.gitignore index b6395ed..e5f0444 100644 --- a/.gitignore +++ b/.gitignore @@ -10,5 +10,4 @@ data/.yarn data/node_modules node_modules .DS_Store -*.bin -ci/cache \ No newline at end of file +*.bin \ No newline at end of file diff --git a/.gitmodules b/.gitmodules index d8b183a..f921d34 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,3 +1,3 @@ [submodule "data"] path = data - url = https://git.btclock.dev/btclock/webui.git + url = https://github.com/btclock/webui.git diff --git a/README.md b/README.md index 1962434..9e22ee3 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,6 @@ # BTClock v3 -[![Latest release](https://git.btclock.dev/btclock/btclock_v3/badges/release.svg)](https://git.btclock.dev/btclock/btclock_v3/releases/latest) - -[![BTClock CI](https://git.btclock.dev/btclock/btclock_v3/badges/workflows/push.yaml/badge.svg)](https://git.btclock.dev/btclock/btclock_v3/actions?workflow=push.yaml&actor=0&status=0) +[![BTClock CI](https://github.com/btclock/btclock_v3/actions/workflows/tagging.yml/badge.svg)](https://github.com/btclock/btclock_v3/actions/workflows/tagging.yml) Software for the BTClock project. @@ -14,46 +12,12 @@ Biggest differences with v2 are: - Added market capitalization screen - LED flash on new block (and focus to block height screen on new block) -New features: -- BitAxe integration -- Nostr Zap notifier -- Multiple mining pool stats integrations - "Steal focus on new block" means that when a new block is mined, the display will switch to the block height screen if it's not on it already. -See the [docs](https://git.btclock.dev/btclock/docs) repo for more information and building instructions. +Most [information](https://github.com/btclock/btclock_v2/wiki) about BTClock v2 is still valid for this version. -**NOTE**: The software assumes that the hardware is run in a controlled private network. ~~The Web UI and the OTA update mechanism are not password protected and accessible to anyone in the network. Also, since the device only fetches numbers through WebSockets it will skip server certificate verification to save resources.~~ Since 3.2.0 the WebUI is password protectable and all certificates are verified. OTA update mechanism is not password-protected. +**NOTE**: The software assumes that the hardware is run in a controlled private network. The Web UI and the OTA update mechanism are not password protected and accessible to anyone in the network. Also, since the device only fetches numbers through WebSockets it will skip server certificate verification to save resources. ## Building -Use PlatformIO to build it yourself. Make sure you fetch the [WebUI](https://git.btclock.dev/btclock/webui) submodule. - - -## Mining pool stats -Enable mining pool stats by accessing your btclock's web UI (point a web browser at the device's IP address). - -Under Settings -> Extra Features: toggle Enable Mining Pool Stats. - -New options will appear. Select your mining pool and enter your pool username (Ocean) or api key (Braiins). - -The Mining Pool Earnings screen displays: -* Braiins: Today's mining reward thus far -* Ocean: Your estimated earnings if the pool were to find a block right now - -For solo mining pools, there are no earning estimations. Your username is the onchain withdrawal address, without the worker name. - - -### Braiins Pool integration -Create an API key based on the steps [here](https://academy.braiins.com/en/braiins-pool/monitoring/#api-configuration). - -The key's permissions should be: -* Web Access: no -* API Access: yes -* Access Permissions: Read-only - -Copy the token that is created for the new key. Enter this as your "Mining Pool username or api key" in the btclock web UI. - - -### Ocean integration -Your "Mining Pool username" is just the onchain withdrawal address that you specify when pointing your miners at Ocean. +Use PlatformIO to build it yourself. Make sure you fetch the [WebUI](https://github.com/btclock/webui) submodule. \ No newline at end of file diff --git a/boards/btclock_v8.json b/boards/btclock.json similarity index 92% rename from boards/btclock_v8.json rename to boards/btclock.json index b30bd19..bee4064 100644 --- a/boards/btclock_v8.json +++ b/boards/btclock.json @@ -10,7 +10,7 @@ "-DBOARD_HAS_PSRAM", "-DARDUINO_BTCLOCK", "-DARDUINO_ESP32S3_DEV", - "-DIS_BTCLOCK_V8", + "-DIS_BTCLOCK_S3", "-DARDUINO_USB_MODE=1", "-DARDUINO_RUNNING_CORE=1", "-DARDUINO_EVENT_RUNNING_CORE=1", @@ -20,8 +20,8 @@ "f_flash": "80000000L", "flash_mode": "qio", "psram_type": "opi", - "esp-idf": { - "sdkconfig_path": "boards/sdkconfig.btclock_v8" + "espidf": { + "sdkconfig_path": "boards" }, "hwids": [ [ diff --git a/boards/btclock_rev_b.json b/boards/btclock_rev_b.json deleted file mode 100644 index 446576e..0000000 --- a/boards/btclock_rev_b.json +++ /dev/null @@ -1,60 +0,0 @@ -{ - "build": { - "arduino":{ - "ldscript": "esp32s3_out.ld", - "partitions": "default_8MB.csv" - }, - "core": "esp32", - "extra_flags": [ - "-DBOARD_HAS_PSRAM", - "-DARDUINO_BTCLOCK_REV_B", - "-DARDUINO_ESP32S3_DEV", - "-DIS_BTCLOCK_REV_B", - "-DARDUINO_USB_MODE=1", - "-DARDUINO_RUNNING_CORE=1", - "-DARDUINO_EVENT_RUNNING_CORE=1", - "-DARDUINO_USB_CDC_ON_BOOT=1" - ], - "f_cpu": "240000000L", - "f_flash": "80000000L", - "flash_mode": "qio", - "espidf": { - "sdkconfig_path": "boards" - }, - "hwids": [ - [ - "0x303A", - "0x1001" - ] - ], - "mcu": "esp32s3", - "variant": "esp32s3" - }, - "connectivity": [ - "bluetooth", - "wifi" - ], - "debug": { - "default_tool": "esp-builtin", - "onboard_tools": [ - "esp-builtin" - ], - "openocd_target": "esp32s3.cfg" - }, - "frameworks": [ - "arduino", - "espidf" - ], - "name": "BTClock (rev. B)", - "upload": { - "flash_size": "8MB", - "maximum_ram_size": 327680, - "maximum_size": 8388608, - "use_1200bps_touch": true, - "wait_for_upload_port": true, - "require_upload_port": true, - "speed": 460800 - }, - "url": "http://github.com/btclock", - "vendor": "BTClock" -} \ No newline at end of file diff --git a/boards/sdkconfig.btclock_v8 b/boards/sdkconfig.btclock_v8 deleted file mode 100644 index 0c3b34e..0000000 --- a/boards/sdkconfig.btclock_v8 +++ /dev/null @@ -1,1598 +0,0 @@ -# -# Automatically generated file. DO NOT EDIT. -# Espressif IoT Development Framework (ESP-IDF) Project Configuration -# -CONFIG_IDF_CMAKE=y -CONFIG_IDF_TARGET_ARCH_XTENSA=y -CONFIG_IDF_TARGET="esp32s3" -CONFIG_IDF_TARGET_ESP32S3=y -CONFIG_IDF_FIRMWARE_CHIP_ID=0x0009 - -# -# SDK tool configuration -# -CONFIG_SDK_TOOLPREFIX="xtensa-esp32s3-elf-" -# CONFIG_SDK_TOOLCHAIN_SUPPORTS_TIME_WIDE_64_BITS is not set -# end of SDK tool configuration - -# -# Build type -# -CONFIG_APP_BUILD_TYPE_APP_2NDBOOT=y -# CONFIG_APP_BUILD_TYPE_ELF_RAM is not set -CONFIG_APP_BUILD_GENERATE_BINARIES=y -CONFIG_APP_BUILD_BOOTLOADER=y -CONFIG_APP_BUILD_USE_FLASH_SECTIONS=y -# end of Build type - -# -# Application manager -# -CONFIG_APP_COMPILE_TIME_DATE=y -# CONFIG_APP_EXCLUDE_PROJECT_VER_VAR is not set -# CONFIG_APP_EXCLUDE_PROJECT_NAME_VAR is not set -# CONFIG_APP_PROJECT_VER_FROM_CONFIG is not set -CONFIG_APP_RETRIEVE_LEN_ELF_SHA=16 -# end of Application manager - -# -# Bootloader config -# -CONFIG_BOOTLOADER_OFFSET_IN_FLASH=0x0 -CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_SIZE=y -# CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_DEBUG is not set -# CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_PERF is not set -# CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_NONE is not set -CONFIG_BOOTLOADER_LOG_LEVEL_NONE=y -# CONFIG_BOOTLOADER_LOG_LEVEL_ERROR is not set -# CONFIG_BOOTLOADER_LOG_LEVEL_WARN is not set -# CONFIG_BOOTLOADER_LOG_LEVEL_INFO is not set -# CONFIG_BOOTLOADER_LOG_LEVEL_DEBUG is not set -# CONFIG_BOOTLOADER_LOG_LEVEL_VERBOSE is not set -CONFIG_BOOTLOADER_LOG_LEVEL=0 - -# -# Serial Flash Configurations -# -# CONFIG_BOOTLOADER_FLASH_DC_AWARE is not set -CONFIG_BOOTLOADER_FLASH_XMC_SUPPORT=y -# end of Serial Flash Configurations - -CONFIG_BOOTLOADER_VDDSDIO_BOOST_1_9V=y -# CONFIG_BOOTLOADER_FACTORY_RESET is not set -# CONFIG_BOOTLOADER_APP_TEST is not set -CONFIG_BOOTLOADER_REGION_PROTECTION_ENABLE=y -CONFIG_BOOTLOADER_WDT_ENABLE=y -# CONFIG_BOOTLOADER_WDT_DISABLE_IN_USER_CODE is not set -CONFIG_BOOTLOADER_WDT_TIME_MS=9000 -# CONFIG_BOOTLOADER_APP_ROLLBACK_ENABLE is not set -# CONFIG_BOOTLOADER_SKIP_VALIDATE_IN_DEEP_SLEEP is not set -# CONFIG_BOOTLOADER_SKIP_VALIDATE_ON_POWER_ON is not set -# CONFIG_BOOTLOADER_SKIP_VALIDATE_ALWAYS is not set -CONFIG_BOOTLOADER_RESERVE_RTC_SIZE=0 -# CONFIG_BOOTLOADER_CUSTOM_RESERVE_RTC is not set -# end of Bootloader config - -# -# Security features -# -CONFIG_SECURE_BOOT_SUPPORTS_RSA=y -CONFIG_SECURE_TARGET_HAS_SECURE_ROM_DL_MODE=y -# CONFIG_SECURE_SIGNED_APPS_NO_SECURE_BOOT is not set -# CONFIG_SECURE_BOOT is not set -# CONFIG_SECURE_FLASH_ENC_ENABLED is not set -# end of Security features - -# -# Boot ROM Behavior -# -CONFIG_BOOT_ROM_LOG_ALWAYS_ON=y -# CONFIG_BOOT_ROM_LOG_ALWAYS_OFF is not set -# CONFIG_BOOT_ROM_LOG_ON_GPIO_HIGH is not set -# CONFIG_BOOT_ROM_LOG_ON_GPIO_LOW is not set -# end of Boot ROM Behavior - -# -# Serial flasher config -# -CONFIG_ESPTOOLPY_BAUD_OTHER_VAL=115200 -# CONFIG_ESPTOOLPY_NO_STUB is not set -# CONFIG_ESPTOOLPY_OCT_FLASH is not set -# CONFIG_ESPTOOLPY_FLASHMODE_QIO is not set -# CONFIG_ESPTOOLPY_FLASHMODE_QOUT is not set -CONFIG_ESPTOOLPY_FLASHMODE_DIO=y -# CONFIG_ESPTOOLPY_FLASHMODE_DOUT is not set -CONFIG_ESPTOOLPY_FLASH_SAMPLE_MODE_STR=y -CONFIG_ESPTOOLPY_FLASHMODE="dio" -CONFIG_ESPTOOLPY_S3_STR=y -# CONFIG_ESPTOOLPY_FLASHFREQ_120M is not set -CONFIG_ESPTOOLPY_FLASHFREQ_80M=y -# CONFIG_ESPTOOLPY_FLASHFREQ_40M is not set -# CONFIG_ESPTOOLPY_FLASHFREQ_20M is not set -CONFIG_ESPTOOLPY_FLASHFREQ="80m" -# CONFIG_ESPTOOLPY_FLASHSIZE_1MB is not set -CONFIG_ESPTOOLPY_FLASHSIZE_2MB=y -# CONFIG_ESPTOOLPY_FLASHSIZE_4MB is not set -# CONFIG_ESPTOOLPY_FLASHSIZE_8MB is not set -# CONFIG_ESPTOOLPY_FLASHSIZE_16MB is not set -# CONFIG_ESPTOOLPY_FLASHSIZE_32MB is not set -# CONFIG_ESPTOOLPY_FLASHSIZE_64MB is not set -# CONFIG_ESPTOOLPY_FLASHSIZE_128MB is not set -CONFIG_ESPTOOLPY_FLASHSIZE="2MB" -CONFIG_ESPTOOLPY_FLASHSIZE_DETECT=y -CONFIG_ESPTOOLPY_BEFORE_RESET=y -# CONFIG_ESPTOOLPY_BEFORE_NORESET is not set -CONFIG_ESPTOOLPY_BEFORE="default_reset" -CONFIG_ESPTOOLPY_AFTER_RESET=y -# CONFIG_ESPTOOLPY_AFTER_NORESET is not set -CONFIG_ESPTOOLPY_AFTER="hard_reset" -# CONFIG_ESPTOOLPY_MONITOR_BAUD_CONSOLE is not set -# CONFIG_ESPTOOLPY_MONITOR_BAUD_9600B is not set -# CONFIG_ESPTOOLPY_MONITOR_BAUD_57600B is not set -CONFIG_ESPTOOLPY_MONITOR_BAUD_115200B=y -# CONFIG_ESPTOOLPY_MONITOR_BAUD_230400B is not set -# CONFIG_ESPTOOLPY_MONITOR_BAUD_921600B is not set -# CONFIG_ESPTOOLPY_MONITOR_BAUD_2MB is not set -# CONFIG_ESPTOOLPY_MONITOR_BAUD_OTHER is not set -CONFIG_ESPTOOLPY_MONITOR_BAUD_OTHER_VAL=115200 -CONFIG_ESPTOOLPY_MONITOR_BAUD=115200 -# end of Serial flasher config - -# -# Partition Table -# -CONFIG_PARTITION_TABLE_SINGLE_APP=y -# CONFIG_PARTITION_TABLE_SINGLE_APP_LARGE is not set -# CONFIG_PARTITION_TABLE_TWO_OTA is not set -# CONFIG_PARTITION_TABLE_CUSTOM is not set -CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions.csv" -CONFIG_PARTITION_TABLE_FILENAME="partitions_singleapp.csv" -CONFIG_PARTITION_TABLE_OFFSET=0x8000 -CONFIG_PARTITION_TABLE_MD5=y -# end of Partition Table - -# -# Arduino Configuration -# -CONFIG_ARDUINO_VARIANT="esp32s3" -CONFIG_ENABLE_ARDUINO_DEPENDS=y -# CONFIG_AUTOSTART_ARDUINO is not set -# CONFIG_ARDUINO_RUN_CORE0 is not set -CONFIG_ARDUINO_RUN_CORE1=y -# CONFIG_ARDUINO_RUN_NO_AFFINITY is not set -CONFIG_ARDUINO_RUNNING_CORE=1 -CONFIG_ARDUINO_LOOP_STACK_SIZE=8192 -# CONFIG_ARDUINO_EVENT_RUN_CORE0 is not set -CONFIG_ARDUINO_EVENT_RUN_CORE1=y -# CONFIG_ARDUINO_EVENT_RUN_NO_AFFINITY is not set -CONFIG_ARDUINO_EVENT_RUNNING_CORE=1 -# CONFIG_ARDUINO_SERIAL_EVENT_RUN_CORE0 is not set -# CONFIG_ARDUINO_SERIAL_EVENT_RUN_CORE1 is not set -CONFIG_ARDUINO_SERIAL_EVENT_RUN_NO_AFFINITY=y -CONFIG_ARDUINO_SERIAL_EVENT_TASK_RUNNING_CORE=-1 -CONFIG_ARDUINO_SERIAL_EVENT_TASK_STACK_SIZE=2048 -CONFIG_ARDUINO_SERIAL_EVENT_TASK_PRIORITY=24 -CONFIG_ARDUINO_UDP_RUN_CORE0=y -# CONFIG_ARDUINO_UDP_RUN_CORE1 is not set -# CONFIG_ARDUINO_UDP_RUN_NO_AFFINITY is not set -CONFIG_ARDUINO_UDP_RUNNING_CORE=0 -CONFIG_ARDUINO_UDP_TASK_PRIORITY=3 -# CONFIG_ARDUINO_ISR_IRAM is not set -# CONFIG_DISABLE_HAL_LOCKS is not set - -# -# Debug Log Configuration -# -# CONFIG_ARDUHAL_LOG_DEFAULT_LEVEL_NONE is not set -CONFIG_ARDUHAL_LOG_DEFAULT_LEVEL_ERROR=y -# CONFIG_ARDUHAL_LOG_DEFAULT_LEVEL_WARN is not set -# CONFIG_ARDUHAL_LOG_DEFAULT_LEVEL_INFO is not set -# CONFIG_ARDUHAL_LOG_DEFAULT_LEVEL_DEBUG is not set -# CONFIG_ARDUHAL_LOG_DEFAULT_LEVEL_VERBOSE is not set -CONFIG_ARDUHAL_LOG_DEFAULT_LEVEL=1 -# CONFIG_ARDUHAL_LOG_COLORS is not set -# CONFIG_ARDUHAL_ESP_LOG is not set -# end of Debug Log Configuration - -CONFIG_ARDUHAL_PARTITION_SCHEME_DEFAULT=y -# CONFIG_ARDUHAL_PARTITION_SCHEME_MINIMAL is not set -# CONFIG_ARDUHAL_PARTITION_SCHEME_NO_OTA is not set -# CONFIG_ARDUHAL_PARTITION_SCHEME_HUGE_APP is not set -# CONFIG_ARDUHAL_PARTITION_SCHEME_MIN_SPIFFS is not set -CONFIG_ARDUHAL_PARTITION_SCHEME="default" -# CONFIG_ARDUINO_SELECTIVE_COMPILATION is not set -# end of Arduino Configuration - -# -# Compiler options -# -# CONFIG_COMPILER_OPTIMIZATION_DEFAULT is not set -CONFIG_COMPILER_OPTIMIZATION_SIZE=y -# CONFIG_COMPILER_OPTIMIZATION_PERF is not set -# CONFIG_COMPILER_OPTIMIZATION_NONE is not set -CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_ENABLE=y -# CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_SILENT is not set -# CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_DISABLE is not set -CONFIG_COMPILER_OPTIMIZATION_ASSERTION_LEVEL=2 -# CONFIG_COMPILER_OPTIMIZATION_CHECKS_SILENT is not set -CONFIG_COMPILER_HIDE_PATHS_MACROS=y -CONFIG_COMPILER_CXX_EXCEPTIONS=y -CONFIG_COMPILER_CXX_EXCEPTIONS_EMG_POOL_SIZE=0 -# CONFIG_COMPILER_CXX_RTTI is not set -CONFIG_COMPILER_STACK_CHECK_MODE_NONE=y -# CONFIG_COMPILER_STACK_CHECK_MODE_NORM is not set -# CONFIG_COMPILER_STACK_CHECK_MODE_STRONG is not set -# CONFIG_COMPILER_STACK_CHECK_MODE_ALL is not set -# CONFIG_COMPILER_WARN_WRITE_STRINGS is not set -# CONFIG_COMPILER_DISABLE_GCC8_WARNINGS is not set -# CONFIG_COMPILER_DUMP_RTL_FILES is not set -# end of Compiler options - -# -# Component config -# - -# -# Application Level Tracing -# -# CONFIG_APPTRACE_DEST_JTAG is not set -CONFIG_APPTRACE_DEST_NONE=y -CONFIG_APPTRACE_LOCK_ENABLE=y -# end of Application Level Tracing - -# -# ESP-ASIO -# -# CONFIG_ASIO_SSL_SUPPORT is not set -# end of ESP-ASIO - -# -# Bluetooth -# -# CONFIG_BT_ENABLED is not set -# end of Bluetooth - -# -# CoAP Configuration -# -CONFIG_COAP_MBEDTLS_PSK=y -# CONFIG_COAP_MBEDTLS_PKI is not set -# CONFIG_COAP_MBEDTLS_DEBUG is not set -CONFIG_COAP_LOG_DEFAULT_LEVEL=0 -# end of CoAP Configuration - -# -# Driver configurations -# - -# -# ADC configuration -# -# CONFIG_ADC_FORCE_XPD_FSM is not set -CONFIG_ADC_DISABLE_DAC=y -# CONFIG_ADC_CONTINUOUS_FORCE_USE_ADC2_ON_C3_S3 is not set -# end of ADC configuration - -# -# MCPWM configuration -# -# CONFIG_MCPWM_ISR_IN_IRAM is not set -# end of MCPWM configuration - -# -# SPI configuration -# -# CONFIG_SPI_MASTER_IN_IRAM is not set -CONFIG_SPI_MASTER_ISR_IN_IRAM=y -# CONFIG_SPI_SLAVE_IN_IRAM is not set -CONFIG_SPI_SLAVE_ISR_IN_IRAM=y -# end of SPI configuration - -# -# TWAI configuration -# -# CONFIG_TWAI_ISR_IN_IRAM is not set -# CONFIG_TWAI_ERRATA_FIX_LISTEN_ONLY_DOM is not set -# end of TWAI configuration - -# -# UART configuration -# -# CONFIG_UART_ISR_IN_IRAM is not set -# end of UART configuration - -# -# GDMA Configuration -# -# CONFIG_GDMA_CTRL_FUNC_IN_IRAM is not set -# CONFIG_GDMA_ISR_IRAM_SAFE is not set -# end of GDMA Configuration -# end of Driver configurations - -# -# eFuse Bit Manager -# -# CONFIG_EFUSE_CUSTOM_TABLE is not set -# CONFIG_EFUSE_VIRTUAL is not set -CONFIG_EFUSE_MAX_BLK_LEN=256 -# end of eFuse Bit Manager - -# -# ESP-TLS -# -CONFIG_ESP_TLS_USING_MBEDTLS=y -CONFIG_ESP_TLS_USE_DS_PERIPHERAL=y -# CONFIG_ESP_TLS_CLIENT_SESSION_TICKETS is not set -# CONFIG_ESP_TLS_SERVER is not set -# CONFIG_ESP_TLS_PSK_VERIFICATION is not set -# CONFIG_ESP_TLS_INSECURE is not set -# end of ESP-TLS - -# -# ESP32S3-Specific -# -CONFIG_ESP32S3_REV_MIN_0=y -# CONFIG_ESP32S3_REV_MIN_1 is not set -# CONFIG_ESP32S3_REV_MIN_2 is not set -CONFIG_ESP32S3_REV_MIN_FULL=0 -CONFIG_ESP_REV_MIN_FULL=0 -CONFIG_ESP32S3_REV_MAX_FULL_STR_OPT=y -CONFIG_ESP32S3_REV_MAX_FULL=99 -CONFIG_ESP_REV_MAX_FULL=99 -# CONFIG_ESP32S3_DEFAULT_CPU_FREQ_80 is not set -CONFIG_ESP32S3_DEFAULT_CPU_FREQ_160=y -# CONFIG_ESP32S3_DEFAULT_CPU_FREQ_240 is not set -CONFIG_ESP32S3_DEFAULT_CPU_FREQ_MHZ=160 - -# -# Cache config -# -CONFIG_ESP32S3_INSTRUCTION_CACHE_16KB=y -# CONFIG_ESP32S3_INSTRUCTION_CACHE_32KB is not set -CONFIG_ESP32S3_INSTRUCTION_CACHE_SIZE=0x4000 -# CONFIG_ESP32S3_INSTRUCTION_CACHE_4WAYS is not set -CONFIG_ESP32S3_INSTRUCTION_CACHE_8WAYS=y -CONFIG_ESP32S3_ICACHE_ASSOCIATED_WAYS=8 -# CONFIG_ESP32S3_INSTRUCTION_CACHE_LINE_16B is not set -CONFIG_ESP32S3_INSTRUCTION_CACHE_LINE_32B=y -CONFIG_ESP32S3_INSTRUCTION_CACHE_LINE_SIZE=32 -# CONFIG_ESP32S3_INSTRUCTION_CACHE_WRAP is not set -# CONFIG_ESP32S3_DATA_CACHE_16KB is not set -CONFIG_ESP32S3_DATA_CACHE_32KB=y -# CONFIG_ESP32S3_DATA_CACHE_64KB is not set -CONFIG_ESP32S3_DATA_CACHE_SIZE=0x8000 -# CONFIG_ESP32S3_DATA_CACHE_4WAYS is not set -CONFIG_ESP32S3_DATA_CACHE_8WAYS=y -CONFIG_ESP32S3_DCACHE_ASSOCIATED_WAYS=8 -# CONFIG_ESP32S3_DATA_CACHE_LINE_16B is not set -CONFIG_ESP32S3_DATA_CACHE_LINE_32B=y -# CONFIG_ESP32S3_DATA_CACHE_LINE_64B is not set -CONFIG_ESP32S3_DATA_CACHE_LINE_SIZE=32 -# CONFIG_ESP32S3_DATA_CACHE_WRAP is not set -# end of Cache config - -CONFIG_ESP32S3_SPIRAM_SUPPORT=y - -# -# SPI RAM config -# -# CONFIG_SPIRAM_MODE_QUAD is not set -CONFIG_SPIRAM_MODE_OCT=y -CONFIG_SPIRAM_TYPE_AUTO=y -# CONFIG_SPIRAM_TYPE_ESPPSRAM64 is not set -CONFIG_SPIRAM_SIZE=-1 -CONFIG_SPIRAM_CLK_IO=30 -CONFIG_SPIRAM_CS_IO=26 -# CONFIG_SPIRAM_FETCH_INSTRUCTIONS is not set -# CONFIG_SPIRAM_RODATA is not set -# CONFIG_SPIRAM_ALLOW_STACK_EXTERNAL_MEMORY is not set -# CONFIG_SPIRAM_SPEED_80M is not set -CONFIG_SPIRAM_SPEED_40M=y -CONFIG_SPIRAM=y -CONFIG_SPIRAM_BOOT_INIT=y -# CONFIG_SPIRAM_IGNORE_NOTFOUND is not set -# CONFIG_SPIRAM_USE_MEMMAP is not set -# CONFIG_SPIRAM_USE_CAPS_ALLOC is not set -CONFIG_SPIRAM_USE_MALLOC=y -CONFIG_SPIRAM_MEMTEST=y -CONFIG_SPIRAM_MALLOC_ALWAYSINTERNAL=16384 -CONFIG_SPIRAM_TRY_ALLOCATE_WIFI_LWIP=y -CONFIG_SPIRAM_MALLOC_RESERVE_INTERNAL=32768 -# end of SPI RAM config - -# CONFIG_ESP32S3_TRAX is not set -CONFIG_ESP32S3_TRACEMEM_RESERVE_DRAM=0x0 -# CONFIG_ESP32S3_ULP_COPROC_ENABLED is not set -CONFIG_ESP32S3_ULP_COPROC_RESERVE_MEM=0 -CONFIG_ESP32S3_DEBUG_OCDAWARE=y -CONFIG_ESP32S3_BROWNOUT_DET=y -CONFIG_ESP32S3_BROWNOUT_DET_LVL_SEL_7=y -# CONFIG_ESP32S3_BROWNOUT_DET_LVL_SEL_6 is not set -# CONFIG_ESP32S3_BROWNOUT_DET_LVL_SEL_5 is not set -# CONFIG_ESP32S3_BROWNOUT_DET_LVL_SEL_4 is not set -# CONFIG_ESP32S3_BROWNOUT_DET_LVL_SEL_3 is not set -# CONFIG_ESP32S3_BROWNOUT_DET_LVL_SEL_2 is not set -# CONFIG_ESP32S3_BROWNOUT_DET_LVL_SEL_1 is not set -CONFIG_ESP32S3_BROWNOUT_DET_LVL=7 -CONFIG_ESP32S3_TIME_SYSCALL_USE_RTC_FRC1=y -# CONFIG_ESP32S3_TIME_SYSCALL_USE_RTC is not set -# CONFIG_ESP32S3_TIME_SYSCALL_USE_FRC1 is not set -# CONFIG_ESP32S3_TIME_SYSCALL_USE_NONE is not set -CONFIG_ESP32S3_RTC_CLK_SRC_INT_RC=y -# CONFIG_ESP32S3_RTC_CLK_SRC_EXT_CRYS is not set -# CONFIG_ESP32S3_RTC_CLK_SRC_EXT_OSC is not set -# CONFIG_ESP32S3_RTC_CLK_SRC_INT_8MD256 is not set -CONFIG_ESP32S3_RTC_CLK_CAL_CYCLES=1024 -CONFIG_ESP32S3_DEEP_SLEEP_WAKEUP_DELAY=2000 -# CONFIG_ESP32S3_NO_BLOBS is not set -# CONFIG_ESP32S3_RTCDATA_IN_FAST_MEM is not set -# CONFIG_ESP32S3_USE_FIXED_STATIC_RAM_SIZE is not set -# end of ESP32S3-Specific - -# -# ADC-Calibration -# -# end of ADC-Calibration - -# -# Common ESP-related -# -CONFIG_ESP_ERR_TO_NAME_LOOKUP=y -# end of Common ESP-related - -# -# Ethernet -# -CONFIG_ETH_ENABLED=y -CONFIG_ETH_USE_SPI_ETHERNET=y -# CONFIG_ETH_SPI_ETHERNET_DM9051 is not set -# CONFIG_ETH_SPI_ETHERNET_W5500 is not set -# CONFIG_ETH_SPI_ETHERNET_KSZ8851SNL is not set -# CONFIG_ETH_USE_OPENETH is not set -# end of Ethernet - -# -# Event Loop Library -# -# CONFIG_ESP_EVENT_LOOP_PROFILING is not set -CONFIG_ESP_EVENT_POST_FROM_ISR=y -CONFIG_ESP_EVENT_POST_FROM_IRAM_ISR=y -# end of Event Loop Library - -# -# GDB Stub -# -# end of GDB Stub - -# -# ESP HTTP client -# -CONFIG_ESP_HTTP_CLIENT_ENABLE_HTTPS=y -# CONFIG_ESP_HTTP_CLIENT_ENABLE_BASIC_AUTH is not set -CONFIG_ESP_HTTP_CLIENT_ENABLE_DIGEST_AUTH=y -# end of ESP HTTP client - -# -# HTTP Server -# -CONFIG_HTTPD_MAX_REQ_HDR_LEN=512 -CONFIG_HTTPD_MAX_URI_LEN=512 -CONFIG_HTTPD_ERR_RESP_NO_DELAY=y -CONFIG_HTTPD_PURGE_BUF_LEN=32 -# CONFIG_HTTPD_LOG_PURGE_DATA is not set -# CONFIG_HTTPD_WS_SUPPORT is not set -# end of HTTP Server - -# -# ESP HTTPS OTA -# -# CONFIG_OTA_ALLOW_HTTP is not set -# end of ESP HTTPS OTA - -# -# ESP HTTPS server -# -# CONFIG_ESP_HTTPS_SERVER_ENABLE is not set -# end of ESP HTTPS server - -# -# Hardware Settings -# - -# -# MAC Config -# -CONFIG_ESP_MAC_ADDR_UNIVERSE_WIFI_STA=y -CONFIG_ESP_MAC_ADDR_UNIVERSE_WIFI_AP=y -CONFIG_ESP_MAC_ADDR_UNIVERSE_BT=y -CONFIG_ESP_MAC_ADDR_UNIVERSE_ETH=y -# CONFIG_ESP32S3_UNIVERSAL_MAC_ADDRESSES_TWO is not set -CONFIG_ESP32S3_UNIVERSAL_MAC_ADDRESSES_FOUR=y -CONFIG_ESP32S3_UNIVERSAL_MAC_ADDRESSES=4 -# end of MAC Config - -# -# Sleep Config -# -CONFIG_ESP_SLEEP_RTC_BUS_ISO_WORKAROUND=y -CONFIG_ESP_SLEEP_GPIO_RESET_WORKAROUND=y -CONFIG_ESP_SLEEP_PSRAM_LEAKAGE_WORKAROUND=y -CONFIG_ESP_SLEEP_FLASH_LEAKAGE_WORKAROUND=y -CONFIG_ESP_SLEEP_MSPI_NEED_ALL_IO_PU=y -CONFIG_ESP_SLEEP_GPIO_ENABLE_INTERNAL_RESISTORS=y -# end of Sleep Config - -# -# RTC Clock Config -# -CONFIG_RTC_CLOCK_BBPLL_POWER_ON_WITH_USB=y -# end of RTC Clock Config -# end of Hardware Settings - -# -# IPC (Inter-Processor Call) -# -CONFIG_ESP_IPC_TASK_STACK_SIZE=1536 -CONFIG_ESP_IPC_USES_CALLERS_PRIORITY=y -CONFIG_ESP_IPC_ISR_ENABLE=y -# end of IPC (Inter-Processor Call) - -# -# LCD and Touch Panel -# - -# -# LCD Touch Drivers are maintained in the IDF Component Registry -# - -# -# LCD Peripheral Configuration -# -CONFIG_LCD_PANEL_IO_FORMAT_BUF_SIZE=32 -# CONFIG_LCD_RGB_ISR_IRAM_SAFE is not set -# end of LCD Peripheral Configuration -# end of LCD and Touch Panel - -# -# ESP NETIF Adapter -# -CONFIG_ESP_NETIF_IP_LOST_TIMER_INTERVAL=120 -CONFIG_ESP_NETIF_TCPIP_LWIP=y -# CONFIG_ESP_NETIF_LOOPBACK is not set -CONFIG_ESP_NETIF_TCPIP_ADAPTER_COMPATIBLE_LAYER=y -# end of ESP NETIF Adapter - -# -# PHY -# -CONFIG_ESP_PHY_CALIBRATION_AND_DATA_STORAGE=y -# CONFIG_ESP_PHY_INIT_DATA_IN_PARTITION is not set -CONFIG_ESP_PHY_MAX_WIFI_TX_POWER=20 -CONFIG_ESP_PHY_MAX_TX_POWER=20 -# CONFIG_ESP_PHY_REDUCE_TX_POWER is not set -CONFIG_ESP_PHY_ENABLE_USB=y -CONFIG_ESP_PHY_RF_CAL_PARTIAL=y -# CONFIG_ESP_PHY_RF_CAL_NONE is not set -# CONFIG_ESP_PHY_RF_CAL_FULL is not set -CONFIG_ESP_PHY_CALIBRATION_MODE=0 -# end of PHY - -# -# Power Management -# -# CONFIG_PM_ENABLE is not set -CONFIG_PM_POWER_DOWN_CPU_IN_LIGHT_SLEEP=y -CONFIG_PM_POWER_DOWN_TAGMEM_IN_LIGHT_SLEEP=y -# end of Power Management - -# -# ESP Ringbuf -# -# CONFIG_RINGBUF_PLACE_FUNCTIONS_INTO_FLASH is not set -# CONFIG_RINGBUF_PLACE_ISR_FUNCTIONS_INTO_FLASH is not set -# end of ESP Ringbuf - -# -# ESP System Settings -# -# CONFIG_ESP_SYSTEM_PANIC_PRINT_HALT is not set -CONFIG_ESP_SYSTEM_PANIC_PRINT_REBOOT=y -# CONFIG_ESP_SYSTEM_PANIC_SILENT_REBOOT is not set -# CONFIG_ESP_SYSTEM_PANIC_GDBSTUB is not set -# CONFIG_ESP_SYSTEM_GDBSTUB_RUNTIME is not set -CONFIG_ESP_SYSTEM_RTC_FAST_MEM_AS_HEAP_DEPCHECK=y -CONFIG_ESP_SYSTEM_ALLOW_RTC_FAST_MEM_AS_HEAP=y - -# -# Memory protection -# -# end of Memory protection - -CONFIG_ESP_SYSTEM_EVENT_QUEUE_SIZE=32 -CONFIG_ESP_SYSTEM_EVENT_TASK_STACK_SIZE=2304 -CONFIG_ESP_MAIN_TASK_STACK_SIZE=3584 -CONFIG_ESP_MAIN_TASK_AFFINITY_CPU0=y -# CONFIG_ESP_MAIN_TASK_AFFINITY_CPU1 is not set -# CONFIG_ESP_MAIN_TASK_AFFINITY_NO_AFFINITY is not set -CONFIG_ESP_MAIN_TASK_AFFINITY=0x0 -CONFIG_ESP_MINIMAL_SHARED_STACK_SIZE=2048 -CONFIG_ESP_CONSOLE_UART_DEFAULT=y -# CONFIG_ESP_CONSOLE_USB_CDC is not set -# CONFIG_ESP_CONSOLE_USB_SERIAL_JTAG is not set -# CONFIG_ESP_CONSOLE_UART_CUSTOM is not set -# CONFIG_ESP_CONSOLE_NONE is not set -# CONFIG_ESP_CONSOLE_SECONDARY_NONE is not set -CONFIG_ESP_CONSOLE_SECONDARY_USB_SERIAL_JTAG=y -CONFIG_ESP_CONSOLE_UART=y -CONFIG_ESP_CONSOLE_MULTIPLE_UART=y -CONFIG_ESP_CONSOLE_UART_NUM=0 -CONFIG_ESP_CONSOLE_UART_BAUDRATE=115200 -CONFIG_ESP_INT_WDT=y -CONFIG_ESP_INT_WDT_TIMEOUT_MS=300 -CONFIG_ESP_INT_WDT_CHECK_CPU1=y -CONFIG_ESP_TASK_WDT=y -# CONFIG_ESP_TASK_WDT_PANIC is not set -CONFIG_ESP_TASK_WDT_TIMEOUT_S=5 -CONFIG_ESP_TASK_WDT_CHECK_IDLE_TASK_CPU0=y -CONFIG_ESP_TASK_WDT_CHECK_IDLE_TASK_CPU1=y -# CONFIG_ESP_PANIC_HANDLER_IRAM is not set -# CONFIG_ESP_DEBUG_STUBS_ENABLE is not set -CONFIG_ESP_SYSTEM_CHECK_INT_LEVEL_4=y -CONFIG_ESP_SYSTEM_BBPLL_RECALIB=y -# end of ESP System Settings - -# -# High resolution timer (esp_timer) -# -# CONFIG_ESP_TIMER_PROFILING is not set -CONFIG_ESP_TIME_FUNCS_USE_RTC_TIMER=y -CONFIG_ESP_TIME_FUNCS_USE_ESP_TIMER=y -CONFIG_ESP_TIMER_TASK_STACK_SIZE=3584 -CONFIG_ESP_TIMER_INTERRUPT_LEVEL=1 -# CONFIG_ESP_TIMER_SUPPORTS_ISR_DISPATCH_METHOD is not set -CONFIG_ESP_TIMER_IMPL_SYSTIMER=y -# end of High resolution timer (esp_timer) - -# -# Wi-Fi -# -CONFIG_ESP32_WIFI_ENABLED=y -CONFIG_ESP32_WIFI_STATIC_RX_BUFFER_NUM=6 -CONFIG_ESP32_WIFI_DYNAMIC_RX_BUFFER_NUM=12 -CONFIG_ESP32_WIFI_STATIC_TX_BUFFER=y -CONFIG_ESP32_WIFI_TX_BUFFER_TYPE=0 -CONFIG_ESP32_WIFI_STATIC_TX_BUFFER_NUM=16 -CONFIG_ESP32_WIFI_CACHE_TX_BUFFER_NUM=32 -CONFIG_ESP_WIFI_STATIC_RX_MGMT_BUFFER=y -# CONFIG_ESP_WIFI_DYNAMIC_RX_MGMT_BUFFER is not set -CONFIG_ESP_WIFI_DYNAMIC_RX_MGMT_BUF=0 -CONFIG_ESP_WIFI_RX_MGMT_BUF_NUM_DEF=5 -# CONFIG_ESP32_WIFI_CSI_ENABLED is not set -CONFIG_ESP32_WIFI_AMPDU_TX_ENABLED=y -CONFIG_ESP32_WIFI_TX_BA_WIN=6 -CONFIG_ESP32_WIFI_AMPDU_RX_ENABLED=y -CONFIG_ESP32_WIFI_RX_BA_WIN=6 -# CONFIG_ESP32_WIFI_AMSDU_TX_ENABLED is not set -CONFIG_ESP32_WIFI_NVS_ENABLED=y -CONFIG_ESP32_WIFI_TASK_PINNED_TO_CORE_0=y -# CONFIG_ESP32_WIFI_TASK_PINNED_TO_CORE_1 is not set -CONFIG_ESP32_WIFI_SOFTAP_BEACON_MAX_LEN=752 -CONFIG_ESP32_WIFI_MGMT_SBUF_NUM=32 -CONFIG_ESP32_WIFI_IRAM_OPT=y -CONFIG_ESP32_WIFI_RX_IRAM_OPT=y -CONFIG_ESP32_WIFI_ENABLE_WPA3_SAE=y -# CONFIG_ESP_WIFI_SLP_IRAM_OPT is not set -# CONFIG_ESP_WIFI_FTM_ENABLE is not set -# CONFIG_ESP_WIFI_STA_DISCONNECTED_PM_ENABLE is not set -# CONFIG_ESP_WIFI_GCMP_SUPPORT is not set -# CONFIG_ESP_WIFI_GMAC_SUPPORT is not set -CONFIG_ESP_WIFI_SOFTAP_SUPPORT=y -# CONFIG_ESP_WIFI_SLP_BEACON_LOST_OPT is not set -CONFIG_ESP_WIFI_ESPNOW_MAX_ENCRYPT_NUM=7 -# end of Wi-Fi - -# -# Core dump -# -# CONFIG_ESP_COREDUMP_ENABLE_TO_FLASH is not set -# CONFIG_ESP_COREDUMP_ENABLE_TO_UART is not set -CONFIG_ESP_COREDUMP_ENABLE_TO_NONE=y -# end of Core dump - -# -# FAT Filesystem support -# -# CONFIG_FATFS_CODEPAGE_DYNAMIC is not set -CONFIG_FATFS_CODEPAGE_437=y -# CONFIG_FATFS_CODEPAGE_720 is not set -# CONFIG_FATFS_CODEPAGE_737 is not set -# CONFIG_FATFS_CODEPAGE_771 is not set -# CONFIG_FATFS_CODEPAGE_775 is not set -# CONFIG_FATFS_CODEPAGE_850 is not set -# CONFIG_FATFS_CODEPAGE_852 is not set -# CONFIG_FATFS_CODEPAGE_855 is not set -# CONFIG_FATFS_CODEPAGE_857 is not set -# CONFIG_FATFS_CODEPAGE_860 is not set -# CONFIG_FATFS_CODEPAGE_861 is not set -# CONFIG_FATFS_CODEPAGE_862 is not set -# CONFIG_FATFS_CODEPAGE_863 is not set -# CONFIG_FATFS_CODEPAGE_864 is not set -# CONFIG_FATFS_CODEPAGE_865 is not set -# CONFIG_FATFS_CODEPAGE_866 is not set -# CONFIG_FATFS_CODEPAGE_869 is not set -# CONFIG_FATFS_CODEPAGE_932 is not set -# CONFIG_FATFS_CODEPAGE_936 is not set -# CONFIG_FATFS_CODEPAGE_949 is not set -# CONFIG_FATFS_CODEPAGE_950 is not set -CONFIG_FATFS_CODEPAGE=437 -CONFIG_FATFS_LFN_NONE=y -# CONFIG_FATFS_LFN_HEAP is not set -# CONFIG_FATFS_LFN_STACK is not set -CONFIG_FATFS_FS_LOCK=0 -CONFIG_FATFS_TIMEOUT_MS=10000 -CONFIG_FATFS_PER_FILE_CACHE=y -CONFIG_FATFS_ALLOC_PREFER_EXTRAM=y -# CONFIG_FATFS_USE_FASTSEEK is not set -# end of FAT Filesystem support - -# -# Modbus configuration -# -CONFIG_FMB_COMM_MODE_TCP_EN=y -CONFIG_FMB_TCP_PORT_DEFAULT=502 -CONFIG_FMB_TCP_PORT_MAX_CONN=5 -CONFIG_FMB_TCP_CONNECTION_TOUT_SEC=20 -CONFIG_FMB_COMM_MODE_RTU_EN=y -CONFIG_FMB_COMM_MODE_ASCII_EN=y -CONFIG_FMB_MASTER_TIMEOUT_MS_RESPOND=150 -CONFIG_FMB_MASTER_DELAY_MS_CONVERT=200 -CONFIG_FMB_QUEUE_LENGTH=20 -CONFIG_FMB_PORT_TASK_STACK_SIZE=4096 -CONFIG_FMB_SERIAL_BUF_SIZE=256 -CONFIG_FMB_SERIAL_ASCII_BITS_PER_SYMB=8 -CONFIG_FMB_SERIAL_ASCII_TIMEOUT_RESPOND_MS=1000 -CONFIG_FMB_PORT_TASK_PRIO=10 -# CONFIG_FMB_PORT_TASK_AFFINITY_NO_AFFINITY is not set -CONFIG_FMB_PORT_TASK_AFFINITY_CPU0=y -# CONFIG_FMB_PORT_TASK_AFFINITY_CPU1 is not set -CONFIG_FMB_PORT_TASK_AFFINITY=0x0 -CONFIG_FMB_CONTROLLER_SLAVE_ID_SUPPORT=y -CONFIG_FMB_CONTROLLER_SLAVE_ID=0x00112233 -CONFIG_FMB_CONTROLLER_NOTIFY_TIMEOUT=20 -CONFIG_FMB_CONTROLLER_NOTIFY_QUEUE_SIZE=20 -CONFIG_FMB_CONTROLLER_STACK_SIZE=4096 -CONFIG_FMB_EVENT_QUEUE_TIMEOUT=20 -# CONFIG_FMB_TIMER_PORT_ENABLED is not set -# CONFIG_FMB_TIMER_USE_ISR_DISPATCH_METHOD is not set -# end of Modbus configuration - -# -# FreeRTOS -# -# CONFIG_FREERTOS_UNICORE is not set -CONFIG_FREERTOS_NO_AFFINITY=0x7FFFFFFF -CONFIG_FREERTOS_TICK_SUPPORT_SYSTIMER=y -CONFIG_FREERTOS_CORETIMER_SYSTIMER_LVL1=y -# CONFIG_FREERTOS_CORETIMER_SYSTIMER_LVL3 is not set -CONFIG_FREERTOS_SYSTICK_USES_SYSTIMER=y -CONFIG_FREERTOS_HZ=1000 -CONFIG_FREERTOS_ASSERT_ON_UNTESTED_FUNCTION=y -# CONFIG_FREERTOS_CHECK_STACKOVERFLOW_NONE is not set -# CONFIG_FREERTOS_CHECK_STACKOVERFLOW_PTRVAL is not set -CONFIG_FREERTOS_CHECK_STACKOVERFLOW_CANARY=y -CONFIG_FREERTOS_WATCHPOINT_END_OF_STACK=y -CONFIG_FREERTOS_INTERRUPT_BACKTRACE=y -CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS=1 -CONFIG_FREERTOS_ASSERT_FAIL_ABORT=y -# CONFIG_FREERTOS_ASSERT_FAIL_PRINT_CONTINUE is not set -# CONFIG_FREERTOS_ASSERT_DISABLE is not set -CONFIG_FREERTOS_IDLE_TASK_STACKSIZE=1536 -CONFIG_FREERTOS_ISR_STACKSIZE=1536 -# CONFIG_FREERTOS_LEGACY_HOOKS is not set -CONFIG_FREERTOS_MAX_TASK_NAME_LEN=16 -CONFIG_FREERTOS_SUPPORT_STATIC_ALLOCATION=y -# CONFIG_FREERTOS_ENABLE_STATIC_TASK_CLEAN_UP is not set -CONFIG_FREERTOS_TIMER_TASK_PRIORITY=1 -CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH=3120 -CONFIG_FREERTOS_TIMER_QUEUE_LENGTH=10 -CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE=0 -# CONFIG_FREERTOS_USE_TRACE_FACILITY is not set -# CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS is not set -CONFIG_FREERTOS_CHECK_MUTEX_GIVEN_BY_OWNER=y -# CONFIG_FREERTOS_CHECK_PORT_CRITICAL_COMPLIANCE is not set -# CONFIG_FREERTOS_PLACE_FUNCTIONS_INTO_FLASH is not set -CONFIG_FREERTOS_DEBUG_OCDAWARE=y -CONFIG_FREERTOS_ENABLE_TASK_SNAPSHOT=y -# CONFIG_FREERTOS_PLACE_SNAPSHOT_FUNS_INTO_FLASH is not set -# end of FreeRTOS - -# -# Hardware Abstraction Layer (HAL) and Low Level (LL) -# -CONFIG_HAL_ASSERTION_EQUALS_SYSTEM=y -# CONFIG_HAL_ASSERTION_DISABLE is not set -# CONFIG_HAL_ASSERTION_SILIENT is not set -# CONFIG_HAL_ASSERTION_ENABLE is not set -CONFIG_HAL_DEFAULT_ASSERTION_LEVEL=2 -# end of Hardware Abstraction Layer (HAL) and Low Level (LL) - -# -# Heap memory debugging -# -# CONFIG_HEAP_POISONING_DISABLED is not set -CONFIG_HEAP_POISONING_LIGHT=y -# CONFIG_HEAP_POISONING_COMPREHENSIVE is not set -CONFIG_HEAP_TRACING_OFF=y -# CONFIG_HEAP_TRACING_STANDALONE is not set -# CONFIG_HEAP_TRACING_TOHOST is not set -# CONFIG_HEAP_TASK_TRACKING is not set -# CONFIG_HEAP_ABORT_WHEN_ALLOCATION_FAILS is not set -# end of Heap memory debugging - -# -# jsmn -# -# CONFIG_JSMN_PARENT_LINKS is not set -# CONFIG_JSMN_STRICT is not set -# end of jsmn - -# -# libsodium -# -# end of libsodium - -# -# Log output -# -CONFIG_LOG_DEFAULT_LEVEL_NONE=y -# CONFIG_LOG_DEFAULT_LEVEL_ERROR is not set -# CONFIG_LOG_DEFAULT_LEVEL_WARN is not set -# CONFIG_LOG_DEFAULT_LEVEL_INFO is not set -# CONFIG_LOG_DEFAULT_LEVEL_DEBUG is not set -# CONFIG_LOG_DEFAULT_LEVEL_VERBOSE is not set -CONFIG_LOG_DEFAULT_LEVEL=0 -CONFIG_LOG_MAXIMUM_EQUALS_DEFAULT=y -# CONFIG_LOG_MAXIMUM_LEVEL_ERROR is not set -# CONFIG_LOG_MAXIMUM_LEVEL_WARN is not set -# CONFIG_LOG_MAXIMUM_LEVEL_INFO is not set -# CONFIG_LOG_MAXIMUM_LEVEL_DEBUG is not set -# CONFIG_LOG_MAXIMUM_LEVEL_VERBOSE is not set -CONFIG_LOG_MAXIMUM_LEVEL=0 -CONFIG_LOG_COLORS=y -CONFIG_LOG_TIMESTAMP_SOURCE_RTOS=y -# CONFIG_LOG_TIMESTAMP_SOURCE_SYSTEM is not set -# end of Log output - -# -# LWIP -# -CONFIG_LWIP_LOCAL_HOSTNAME="espressif" -# CONFIG_LWIP_NETIF_API is not set -CONFIG_LWIP_TCPIP_TASK_PRIO=18 -# CONFIG_LWIP_TCPIP_CORE_LOCKING is not set -# CONFIG_LWIP_CHECK_THREAD_SAFETY is not set -CONFIG_LWIP_DNS_SUPPORT_MDNS_QUERIES=y -# CONFIG_LWIP_L2_TO_L3_COPY is not set -# CONFIG_LWIP_IRAM_OPTIMIZATION is not set -CONFIG_LWIP_TIMERS_ONDEMAND=y -CONFIG_LWIP_MAX_SOCKETS=10 -# CONFIG_LWIP_USE_ONLY_LWIP_SELECT is not set -# CONFIG_LWIP_SO_LINGER is not set -CONFIG_LWIP_SO_REUSE=y -CONFIG_LWIP_SO_REUSE_RXTOALL=y -CONFIG_LWIP_SO_RCVBUF=y -# CONFIG_LWIP_NETBUF_RECVINFO is not set -CONFIG_LWIP_IP_DEFAULT_TTL=64 -CONFIG_LWIP_IP4_FRAG=y -CONFIG_LWIP_IP6_FRAG=y -# CONFIG_LWIP_IP4_REASSEMBLY is not set -# CONFIG_LWIP_IP6_REASSEMBLY is not set -# CONFIG_LWIP_IP_FORWARD is not set -# CONFIG_LWIP_STATS is not set -# CONFIG_LWIP_ETHARP_TRUST_IP_MAC is not set -CONFIG_LWIP_ESP_GRATUITOUS_ARP=y -CONFIG_LWIP_GARP_TMR_INTERVAL=60 -CONFIG_LWIP_ESP_MLDV6_REPORT=y -CONFIG_LWIP_MLDV6_TMR_INTERVAL=40 -CONFIG_LWIP_TCPIP_RECVMBOX_SIZE=32 -CONFIG_LWIP_DHCP_DOES_ARP_CHECK=y -# CONFIG_LWIP_DHCP_DISABLE_CLIENT_ID is not set -CONFIG_LWIP_DHCP_DISABLE_VENDOR_CLASS_ID=y -# CONFIG_LWIP_DHCP_RESTORE_LAST_IP is not set -CONFIG_LWIP_DHCP_OPTIONS_LEN=68 -CONFIG_LWIP_DHCP_COARSE_TIMER_SECS=1 - -# -# DHCP server -# -CONFIG_LWIP_DHCPS=y -CONFIG_LWIP_DHCPS_LEASE_UNIT=60 -CONFIG_LWIP_DHCPS_MAX_STATION_NUM=8 -# end of DHCP server - -# CONFIG_LWIP_AUTOIP is not set -CONFIG_LWIP_IPV6=y -# CONFIG_LWIP_IPV6_AUTOCONFIG is not set -CONFIG_LWIP_IPV6_NUM_ADDRESSES=3 -# CONFIG_LWIP_IPV6_FORWARD is not set -# CONFIG_LWIP_NETIF_STATUS_CALLBACK is not set -CONFIG_LWIP_NETIF_LOOPBACK=y -CONFIG_LWIP_LOOPBACK_MAX_PBUFS=8 - -# -# TCP -# -CONFIG_LWIP_MAX_ACTIVE_TCP=16 -CONFIG_LWIP_MAX_LISTENING_TCP=16 -CONFIG_LWIP_TCP_HIGH_SPEED_RETRANSMISSION=y -CONFIG_LWIP_TCP_MAXRTX=12 -CONFIG_LWIP_TCP_SYNMAXRTX=12 -CONFIG_LWIP_TCP_MSS=1440 -CONFIG_LWIP_TCP_TMR_INTERVAL=250 -CONFIG_LWIP_TCP_MSL=60000 -CONFIG_LWIP_TCP_FIN_WAIT_TIMEOUT=20000 -CONFIG_LWIP_TCP_SND_BUF_DEFAULT=5760 -CONFIG_LWIP_TCP_WND_DEFAULT=5760 -CONFIG_LWIP_TCP_RECVMBOX_SIZE=6 -CONFIG_LWIP_TCP_QUEUE_OOSEQ=y -CONFIG_LWIP_TCP_OOSEQ_TIMEOUT=6 -CONFIG_LWIP_TCP_OOSEQ_MAX_PBUFS=0 -# CONFIG_LWIP_TCP_SACK_OUT is not set -# CONFIG_LWIP_TCP_KEEP_CONNECTION_WHEN_IP_CHANGES is not set -CONFIG_LWIP_TCP_OVERSIZE_MSS=y -# CONFIG_LWIP_TCP_OVERSIZE_QUARTER_MSS is not set -# CONFIG_LWIP_TCP_OVERSIZE_DISABLE is not set -# CONFIG_LWIP_WND_SCALE is not set -CONFIG_LWIP_TCP_RTO_TIME=1500 -# end of TCP - -# -# UDP -# -CONFIG_LWIP_MAX_UDP_PCBS=16 -CONFIG_LWIP_UDP_RECVMBOX_SIZE=6 -# end of UDP - -# -# Checksums -# -# CONFIG_LWIP_CHECKSUM_CHECK_IP is not set -# CONFIG_LWIP_CHECKSUM_CHECK_UDP is not set -CONFIG_LWIP_CHECKSUM_CHECK_ICMP=y -# end of Checksums - -CONFIG_LWIP_TCPIP_TASK_STACK_SIZE=3072 -CONFIG_LWIP_TCPIP_TASK_AFFINITY_NO_AFFINITY=y -# CONFIG_LWIP_TCPIP_TASK_AFFINITY_CPU0 is not set -# CONFIG_LWIP_TCPIP_TASK_AFFINITY_CPU1 is not set -CONFIG_LWIP_TCPIP_TASK_AFFINITY=0x7FFFFFFF -# CONFIG_LWIP_PPP_SUPPORT is not set -CONFIG_LWIP_IPV6_MEMP_NUM_ND6_QUEUE=3 -CONFIG_LWIP_IPV6_ND6_NUM_NEIGHBORS=5 -# CONFIG_LWIP_SLIP_SUPPORT is not set - -# -# ICMP -# -CONFIG_LWIP_ICMP=y -# CONFIG_LWIP_MULTICAST_PING is not set -# CONFIG_LWIP_BROADCAST_PING is not set -# end of ICMP - -# -# LWIP RAW API -# -CONFIG_LWIP_MAX_RAW_PCBS=16 -# end of LWIP RAW API - -# -# SNTP -# -CONFIG_LWIP_SNTP_MAX_SERVERS=1 -# CONFIG_LWIP_DHCP_GET_NTP_SRV is not set -CONFIG_LWIP_SNTP_UPDATE_DELAY=3600000 -# end of SNTP - -# -# DNS -# -CONFIG_LWIP_DNS_MAX_SERVERS=3 -# CONFIG_LWIP_FALLBACK_DNS_SERVER_SUPPORT is not set -# end of DNS - -CONFIG_LWIP_ESP_LWIP_ASSERT=y - -# -# Hooks -# -# CONFIG_LWIP_HOOK_TCP_ISN_NONE is not set -CONFIG_LWIP_HOOK_TCP_ISN_DEFAULT=y -# CONFIG_LWIP_HOOK_TCP_ISN_CUSTOM is not set -CONFIG_LWIP_HOOK_IP6_ROUTE_NONE=y -# CONFIG_LWIP_HOOK_IP6_ROUTE_DEFAULT is not set -# CONFIG_LWIP_HOOK_IP6_ROUTE_CUSTOM is not set -CONFIG_LWIP_HOOK_ND6_GET_GW_NONE=y -# CONFIG_LWIP_HOOK_ND6_GET_GW_DEFAULT is not set -# CONFIG_LWIP_HOOK_ND6_GET_GW_CUSTOM is not set -CONFIG_LWIP_HOOK_NETCONN_EXT_RESOLVE_NONE=y -# CONFIG_LWIP_HOOK_NETCONN_EXT_RESOLVE_DEFAULT is not set -# CONFIG_LWIP_HOOK_NETCONN_EXT_RESOLVE_CUSTOM is not set -# end of Hooks - -# CONFIG_LWIP_DEBUG is not set -# end of LWIP - -# -# mbedTLS -# -CONFIG_MBEDTLS_INTERNAL_MEM_ALLOC=y -# CONFIG_MBEDTLS_EXTERNAL_MEM_ALLOC is not set -# CONFIG_MBEDTLS_DEFAULT_MEM_ALLOC is not set -# CONFIG_MBEDTLS_CUSTOM_MEM_ALLOC is not set -CONFIG_MBEDTLS_ASYMMETRIC_CONTENT_LEN=y -CONFIG_MBEDTLS_SSL_IN_CONTENT_LEN=16384 -CONFIG_MBEDTLS_SSL_OUT_CONTENT_LEN=4096 -# CONFIG_MBEDTLS_DYNAMIC_BUFFER is not set -# CONFIG_MBEDTLS_DEBUG is not set - -# -# mbedTLS v2.28.x related -# -# CONFIG_MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH is not set -# CONFIG_MBEDTLS_X509_TRUSTED_CERT_CALLBACK is not set -# CONFIG_MBEDTLS_SSL_CONTEXT_SERIALIZATION is not set -CONFIG_MBEDTLS_SSL_KEEP_PEER_CERTIFICATE=y -# end of mbedTLS v2.28.x related - -# -# Certificate Bundle -# -CONFIG_MBEDTLS_CERTIFICATE_BUNDLE=y -CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_DEFAULT_FULL=y -# CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_DEFAULT_CMN is not set -# CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_DEFAULT_NONE is not set -# CONFIG_MBEDTLS_CUSTOM_CERTIFICATE_BUNDLE is not set -CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_MAX_CERTS=200 -# end of Certificate Bundle - -# CONFIG_MBEDTLS_ECP_RESTARTABLE is not set -# CONFIG_MBEDTLS_CMAC_C is not set -CONFIG_MBEDTLS_HARDWARE_AES=y -CONFIG_MBEDTLS_AES_USE_INTERRUPT=y -CONFIG_MBEDTLS_HARDWARE_MPI=y -CONFIG_MBEDTLS_HARDWARE_SHA=y -CONFIG_MBEDTLS_ROM_MD5=y -# CONFIG_MBEDTLS_ATCA_HW_ECDSA_SIGN is not set -# CONFIG_MBEDTLS_ATCA_HW_ECDSA_VERIFY is not set -CONFIG_MBEDTLS_HAVE_TIME=y -# CONFIG_MBEDTLS_HAVE_TIME_DATE is not set -CONFIG_MBEDTLS_ECDSA_DETERMINISTIC=y -CONFIG_MBEDTLS_SHA512_C=y -CONFIG_MBEDTLS_TLS_SERVER_AND_CLIENT=y -# CONFIG_MBEDTLS_TLS_SERVER_ONLY is not set -# CONFIG_MBEDTLS_TLS_CLIENT_ONLY is not set -# CONFIG_MBEDTLS_TLS_DISABLED is not set -CONFIG_MBEDTLS_TLS_SERVER=y -CONFIG_MBEDTLS_TLS_CLIENT=y -CONFIG_MBEDTLS_TLS_ENABLED=y - -# -# TLS Key Exchange Methods -# -CONFIG_MBEDTLS_PSK_MODES=y -CONFIG_MBEDTLS_KEY_EXCHANGE_PSK=y -CONFIG_MBEDTLS_KEY_EXCHANGE_DHE_PSK=y -CONFIG_MBEDTLS_KEY_EXCHANGE_ECDHE_PSK=y -CONFIG_MBEDTLS_KEY_EXCHANGE_RSA_PSK=y -CONFIG_MBEDTLS_KEY_EXCHANGE_RSA=y -CONFIG_MBEDTLS_KEY_EXCHANGE_DHE_RSA=y -CONFIG_MBEDTLS_KEY_EXCHANGE_ELLIPTIC_CURVE=y -CONFIG_MBEDTLS_KEY_EXCHANGE_ECDHE_RSA=y -CONFIG_MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA=y -CONFIG_MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA=y -CONFIG_MBEDTLS_KEY_EXCHANGE_ECDH_RSA=y -# end of TLS Key Exchange Methods - -CONFIG_MBEDTLS_SSL_RENEGOTIATION=y -# CONFIG_MBEDTLS_SSL_PROTO_SSL3 is not set -CONFIG_MBEDTLS_SSL_PROTO_TLS1=y -CONFIG_MBEDTLS_SSL_PROTO_TLS1_1=y -CONFIG_MBEDTLS_SSL_PROTO_TLS1_2=y -# CONFIG_MBEDTLS_SSL_PROTO_GMTSSL1_1 is not set -# CONFIG_MBEDTLS_SSL_PROTO_DTLS is not set -CONFIG_MBEDTLS_SSL_ALPN=y -CONFIG_MBEDTLS_CLIENT_SSL_SESSION_TICKETS=y -CONFIG_MBEDTLS_X509_CHECK_KEY_USAGE=y -CONFIG_MBEDTLS_X509_CHECK_EXTENDED_KEY_USAGE=y -CONFIG_MBEDTLS_SERVER_SSL_SESSION_TICKETS=y - -# -# Symmetric Ciphers -# -CONFIG_MBEDTLS_AES_C=y -# CONFIG_MBEDTLS_CAMELLIA_C is not set -# CONFIG_MBEDTLS_DES_C is not set -CONFIG_MBEDTLS_RC4_DISABLED=y -# CONFIG_MBEDTLS_RC4_ENABLED_NO_DEFAULT is not set -# CONFIG_MBEDTLS_RC4_ENABLED is not set -# CONFIG_MBEDTLS_BLOWFISH_C is not set -# CONFIG_MBEDTLS_XTEA_C is not set -CONFIG_MBEDTLS_CCM_C=y -CONFIG_MBEDTLS_GCM_C=y -# CONFIG_MBEDTLS_NIST_KW_C is not set -# end of Symmetric Ciphers - -# CONFIG_MBEDTLS_RIPEMD160_C is not set - -# -# Certificates -# -CONFIG_MBEDTLS_PEM_PARSE_C=y -CONFIG_MBEDTLS_PEM_WRITE_C=y -CONFIG_MBEDTLS_X509_CRL_PARSE_C=y -CONFIG_MBEDTLS_X509_CSR_PARSE_C=y -# end of Certificates - -CONFIG_MBEDTLS_ECP_C=y -CONFIG_MBEDTLS_ECDH_C=y -CONFIG_MBEDTLS_ECDSA_C=y -# CONFIG_MBEDTLS_ECJPAKE_C is not set -CONFIG_MBEDTLS_ECP_DP_SECP192R1_ENABLED=y -CONFIG_MBEDTLS_ECP_DP_SECP224R1_ENABLED=y -CONFIG_MBEDTLS_ECP_DP_SECP256R1_ENABLED=y -CONFIG_MBEDTLS_ECP_DP_SECP384R1_ENABLED=y -CONFIG_MBEDTLS_ECP_DP_SECP521R1_ENABLED=y -CONFIG_MBEDTLS_ECP_DP_SECP192K1_ENABLED=y -CONFIG_MBEDTLS_ECP_DP_SECP224K1_ENABLED=y -CONFIG_MBEDTLS_ECP_DP_SECP256K1_ENABLED=y -CONFIG_MBEDTLS_ECP_DP_BP256R1_ENABLED=y -CONFIG_MBEDTLS_ECP_DP_BP384R1_ENABLED=y -CONFIG_MBEDTLS_ECP_DP_BP512R1_ENABLED=y -CONFIG_MBEDTLS_ECP_DP_CURVE25519_ENABLED=y -CONFIG_MBEDTLS_ECP_NIST_OPTIM=y -# CONFIG_MBEDTLS_POLY1305_C is not set -# CONFIG_MBEDTLS_CHACHA20_C is not set -# CONFIG_MBEDTLS_HKDF_C is not set -# CONFIG_MBEDTLS_THREADING_C is not set -# CONFIG_MBEDTLS_LARGE_KEY_SOFTWARE_MPI is not set -# CONFIG_MBEDTLS_SECURITY_RISKS is not set -# end of mbedTLS - -# -# mDNS -# -CONFIG_MDNS_MAX_SERVICES=10 -CONFIG_MDNS_TASK_PRIORITY=1 -CONFIG_MDNS_TASK_STACK_SIZE=4096 -# CONFIG_MDNS_TASK_AFFINITY_NO_AFFINITY is not set -CONFIG_MDNS_TASK_AFFINITY_CPU0=y -# CONFIG_MDNS_TASK_AFFINITY_CPU1 is not set -CONFIG_MDNS_TASK_AFFINITY=0x0 -CONFIG_MDNS_SERVICE_ADD_TIMEOUT_MS=2000 -# CONFIG_MDNS_STRICT_MODE is not set -CONFIG_MDNS_TIMER_PERIOD_MS=100 -# CONFIG_MDNS_NETWORKING_SOCKET is not set -CONFIG_MDNS_MULTIPLE_INSTANCE=y -# end of mDNS - -# -# ESP-MQTT Configurations -# -CONFIG_MQTT_PROTOCOL_311=y -CONFIG_MQTT_TRANSPORT_SSL=y -CONFIG_MQTT_TRANSPORT_WEBSOCKET=y -CONFIG_MQTT_TRANSPORT_WEBSOCKET_SECURE=y -# CONFIG_MQTT_MSG_ID_INCREMENTAL is not set -# CONFIG_MQTT_SKIP_PUBLISH_IF_DISCONNECTED is not set -# CONFIG_MQTT_REPORT_DELETED_MESSAGES is not set -# CONFIG_MQTT_USE_CUSTOM_CONFIG is not set -# CONFIG_MQTT_TASK_CORE_SELECTION_ENABLED is not set -# CONFIG_MQTT_CUSTOM_OUTBOX is not set -# end of ESP-MQTT Configurations - -# -# Newlib -# -CONFIG_NEWLIB_STDOUT_LINE_ENDING_CRLF=y -# CONFIG_NEWLIB_STDOUT_LINE_ENDING_LF is not set -# CONFIG_NEWLIB_STDOUT_LINE_ENDING_CR is not set -# CONFIG_NEWLIB_STDIN_LINE_ENDING_CRLF is not set -# CONFIG_NEWLIB_STDIN_LINE_ENDING_LF is not set -CONFIG_NEWLIB_STDIN_LINE_ENDING_CR=y -CONFIG_NEWLIB_NANO_FORMAT=y -# end of Newlib - -# -# NVS -# -# CONFIG_NVS_ASSERT_ERROR_CHECK is not set -# end of NVS - -# -# OpenSSL -# -# CONFIG_OPENSSL_DEBUG is not set -CONFIG_OPENSSL_ERROR_STACK=y -# CONFIG_OPENSSL_ASSERT_DO_NOTHING is not set -CONFIG_OPENSSL_ASSERT_EXIT=y -# end of OpenSSL - -# -# OpenThread -# -# CONFIG_OPENTHREAD_ENABLED is not set -# end of OpenThread - -# -# PThreads -# -CONFIG_PTHREAD_TASK_PRIO_DEFAULT=5 -CONFIG_PTHREAD_TASK_STACK_SIZE_DEFAULT=3072 -CONFIG_PTHREAD_STACK_MIN=768 -CONFIG_PTHREAD_DEFAULT_CORE_NO_AFFINITY=y -# CONFIG_PTHREAD_DEFAULT_CORE_0 is not set -# CONFIG_PTHREAD_DEFAULT_CORE_1 is not set -CONFIG_PTHREAD_TASK_CORE_DEFAULT=-1 -CONFIG_PTHREAD_TASK_NAME_DEFAULT="pthread" -# end of PThreads - -# -# Main Flash configuration -# - -# -# Optional and Experimental Features (READ DOCS FIRST) -# - -# -# Features here require specific hardware (READ DOCS FIRST!) -# -# CONFIG_SPI_FLASH_HPM_ENA is not set -CONFIG_SPI_FLASH_HPM_AUTO=y -# CONFIG_SPI_FLASH_HPM_DIS is not set -CONFIG_SPI_FLASH_HPM_ON=y -CONFIG_SPI_FLASH_HPM_DC_AUTO=y -# CONFIG_SPI_FLASH_HPM_DC_DISABLE is not set -# end of Optional and Experimental Features (READ DOCS FIRST) -# end of Main Flash configuration - -# -# SPI Flash driver -# -# CONFIG_SPI_FLASH_VERIFY_WRITE is not set -# CONFIG_SPI_FLASH_ENABLE_COUNTERS is not set -CONFIG_SPI_FLASH_ROM_DRIVER_PATCH=y -# CONFIG_SPI_FLASH_ROM_IMPL is not set -CONFIG_SPI_FLASH_DANGEROUS_WRITE_ABORTS=y -# CONFIG_SPI_FLASH_DANGEROUS_WRITE_FAILS is not set -# CONFIG_SPI_FLASH_DANGEROUS_WRITE_ALLOWED is not set -# CONFIG_SPI_FLASH_USE_LEGACY_IMPL is not set -# CONFIG_SPI_FLASH_SHARE_SPI1_BUS is not set -# CONFIG_SPI_FLASH_BYPASS_BLOCK_ERASE is not set -CONFIG_SPI_FLASH_YIELD_DURING_ERASE=y -CONFIG_SPI_FLASH_ERASE_YIELD_DURATION_MS=20 -CONFIG_SPI_FLASH_ERASE_YIELD_TICKS=1 -CONFIG_SPI_FLASH_WRITE_CHUNK_SIZE=8192 -# CONFIG_SPI_FLASH_SIZE_OVERRIDE is not set -# CONFIG_SPI_FLASH_CHECK_ERASE_TIMEOUT_DISABLED is not set -# CONFIG_SPI_FLASH_OVERRIDE_CHIP_DRIVER_LIST is not set - -# -# Auto-detect flash chips -# -CONFIG_SPI_FLASH_SUPPORT_ISSI_CHIP=y -CONFIG_SPI_FLASH_SUPPORT_MXIC_CHIP=y -CONFIG_SPI_FLASH_SUPPORT_GD_CHIP=y -CONFIG_SPI_FLASH_SUPPORT_WINBOND_CHIP=y -CONFIG_SPI_FLASH_SUPPORT_BOYA_CHIP=y -CONFIG_SPI_FLASH_SUPPORT_TH_CHIP=y -CONFIG_SPI_FLASH_SUPPORT_MXIC_OPI_CHIP=y -# end of Auto-detect flash chips - -CONFIG_SPI_FLASH_ENABLE_ENCRYPTED_READ_WRITE=y -# end of SPI Flash driver - -# -# SPIFFS Configuration -# -CONFIG_SPIFFS_MAX_PARTITIONS=3 - -# -# SPIFFS Cache Configuration -# -CONFIG_SPIFFS_CACHE=y -CONFIG_SPIFFS_CACHE_WR=y -# CONFIG_SPIFFS_CACHE_STATS is not set -# end of SPIFFS Cache Configuration - -CONFIG_SPIFFS_PAGE_CHECK=y -CONFIG_SPIFFS_GC_MAX_RUNS=10 -# CONFIG_SPIFFS_GC_STATS is not set -CONFIG_SPIFFS_PAGE_SIZE=256 -CONFIG_SPIFFS_OBJ_NAME_LEN=32 -# CONFIG_SPIFFS_FOLLOW_SYMLINKS is not set -CONFIG_SPIFFS_USE_MAGIC=y -CONFIG_SPIFFS_USE_MAGIC_LENGTH=y -CONFIG_SPIFFS_META_LENGTH=4 -CONFIG_SPIFFS_USE_MTIME=y - -# -# Debug Configuration -# -# CONFIG_SPIFFS_DBG is not set -# CONFIG_SPIFFS_API_DBG is not set -# CONFIG_SPIFFS_GC_DBG is not set -# CONFIG_SPIFFS_CACHE_DBG is not set -# CONFIG_SPIFFS_CHECK_DBG is not set -# CONFIG_SPIFFS_TEST_VISUALISATION is not set -# end of Debug Configuration -# end of SPIFFS Configuration - -# -# TCP Transport -# - -# -# Websocket -# -CONFIG_WS_TRANSPORT=y -CONFIG_WS_BUFFER_SIZE=1024 -# end of Websocket -# end of TCP Transport - -# -# TinyUSB Stack -# -# CONFIG_TINYUSB is not set -# end of TinyUSB Stack - -# -# Unity unit testing library -# -CONFIG_UNITY_ENABLE_FLOAT=y -CONFIG_UNITY_ENABLE_DOUBLE=y -# CONFIG_UNITY_ENABLE_64BIT is not set -# CONFIG_UNITY_ENABLE_COLOR is not set -CONFIG_UNITY_ENABLE_IDF_TEST_RUNNER=y -# CONFIG_UNITY_ENABLE_FIXTURE is not set -# CONFIG_UNITY_ENABLE_BACKTRACE_ON_FAIL is not set -# end of Unity unit testing library - -# -# USB-OTG -# -CONFIG_USB_OTG_SUPPORTED=y -CONFIG_USB_HOST_CONTROL_TRANSFER_MAX_SIZE=256 -CONFIG_USB_HOST_HW_BUFFER_BIAS_BALANCED=y -# CONFIG_USB_HOST_HW_BUFFER_BIAS_IN is not set -# CONFIG_USB_HOST_HW_BUFFER_BIAS_PERIODIC_OUT is not set - -# -# Root Hub configuration -# -CONFIG_USB_HOST_DEBOUNCE_DELAY_MS=250 -CONFIG_USB_HOST_RESET_HOLD_MS=30 -CONFIG_USB_HOST_RESET_RECOVERY_MS=30 -CONFIG_USB_HOST_SET_ADDR_RECOVERY_MS=10 -# end of Root Hub configuration -# end of USB-OTG - -# -# Virtual file system -# -CONFIG_VFS_SUPPORT_IO=y -CONFIG_VFS_SUPPORT_DIR=y -CONFIG_VFS_SUPPORT_SELECT=y -CONFIG_VFS_SUPPRESS_SELECT_DEBUG_OUTPUT=y -CONFIG_VFS_SUPPORT_TERMIOS=y - -# -# Host File System I/O (Semihosting) -# -CONFIG_VFS_SEMIHOSTFS_MAX_MOUNT_POINTS=1 -# end of Host File System I/O (Semihosting) -# end of Virtual file system - -# -# Wear Levelling -# -# CONFIG_WL_SECTOR_SIZE_512 is not set -CONFIG_WL_SECTOR_SIZE_4096=y -CONFIG_WL_SECTOR_SIZE=4096 -# end of Wear Levelling - -# -# Wi-Fi Provisioning Manager -# -CONFIG_WIFI_PROV_SCAN_MAX_ENTRIES=16 -CONFIG_WIFI_PROV_AUTOSTOP_TIMEOUT=30 -# CONFIG_WIFI_PROV_BLE_FORCE_ENCRYPTION is not set -# end of Wi-Fi Provisioning Manager - -# -# Supplicant -# -CONFIG_WPA_MBEDTLS_CRYPTO=y -# CONFIG_WPA_WAPI_PSK is not set -# CONFIG_WPA_SUITE_B_192 is not set -# CONFIG_WPA_DEBUG_PRINT is not set -# CONFIG_WPA_TESTING_OPTIONS is not set -# CONFIG_WPA_WPS_STRICT is not set -# CONFIG_WPA_11KV_SUPPORT is not set -# CONFIG_WPA_MBO_SUPPORT is not set -# CONFIG_WPA_DPP_SUPPORT is not set -# end of Supplicant - -# -# LittleFS -# -# CONFIG_LITTLEFS_SDMMC_SUPPORT is not set -CONFIG_LITTLEFS_MAX_PARTITIONS=3 -CONFIG_LITTLEFS_PAGE_SIZE=256 -CONFIG_LITTLEFS_OBJ_NAME_LEN=64 -CONFIG_LITTLEFS_READ_SIZE=128 -CONFIG_LITTLEFS_WRITE_SIZE=128 -CONFIG_LITTLEFS_LOOKAHEAD_SIZE=128 -CONFIG_LITTLEFS_CACHE_SIZE=512 -CONFIG_LITTLEFS_BLOCK_CYCLES=512 -CONFIG_LITTLEFS_USE_MTIME=y -# CONFIG_LITTLEFS_USE_ONLY_HASH is not set -# CONFIG_LITTLEFS_HUMAN_READABLE is not set -CONFIG_LITTLEFS_MTIME_USE_SECONDS=y -# CONFIG_LITTLEFS_MTIME_USE_NONCE is not set -# CONFIG_LITTLEFS_SPIFFS_COMPAT is not set -# CONFIG_LITTLEFS_FLUSH_FILE_EVERY_WRITE is not set -# CONFIG_LITTLEFS_FCNTL_GET_PATH is not set -# CONFIG_LITTLEFS_MULTIVERSION is not set -# CONFIG_LITTLEFS_MALLOC_STRATEGY_DISABLE is not set -CONFIG_LITTLEFS_MALLOC_STRATEGY_DEFAULT=y -# CONFIG_LITTLEFS_MALLOC_STRATEGY_INTERNAL is not set -CONFIG_LITTLEFS_ASSERTS=y -# end of LittleFS -# end of Component config - -# -# Compatibility options -# -# CONFIG_LEGACY_INCLUDE_COMMON_HEADERS is not set -# end of Compatibility options - -# Deprecated options for backward compatibility -CONFIG_TOOLPREFIX="xtensa-esp32s3-elf-" -CONFIG_LOG_BOOTLOADER_LEVEL_NONE=y -# CONFIG_LOG_BOOTLOADER_LEVEL_ERROR is not set -# CONFIG_LOG_BOOTLOADER_LEVEL_WARN is not set -# CONFIG_LOG_BOOTLOADER_LEVEL_INFO is not set -# CONFIG_LOG_BOOTLOADER_LEVEL_DEBUG is not set -# CONFIG_LOG_BOOTLOADER_LEVEL_VERBOSE is not set -CONFIG_LOG_BOOTLOADER_LEVEL=0 -# CONFIG_APP_ROLLBACK_ENABLE is not set -# CONFIG_FLASH_ENCRYPTION_ENABLED is not set -# CONFIG_FLASHMODE_QIO is not set -# CONFIG_FLASHMODE_QOUT is not set -CONFIG_FLASHMODE_DIO=y -# CONFIG_FLASHMODE_DOUT is not set -# CONFIG_MONITOR_BAUD_9600B is not set -# CONFIG_MONITOR_BAUD_57600B is not set -CONFIG_MONITOR_BAUD_115200B=y -# CONFIG_MONITOR_BAUD_230400B is not set -# CONFIG_MONITOR_BAUD_921600B is not set -# CONFIG_MONITOR_BAUD_2MB is not set -# CONFIG_MONITOR_BAUD_OTHER is not set -CONFIG_MONITOR_BAUD_OTHER_VAL=115200 -CONFIG_MONITOR_BAUD=115200 -# CONFIG_COMPILER_OPTIMIZATION_LEVEL_DEBUG is not set -CONFIG_COMPILER_OPTIMIZATION_LEVEL_RELEASE=y -CONFIG_OPTIMIZATION_ASSERTIONS_ENABLED=y -# CONFIG_OPTIMIZATION_ASSERTIONS_SILENT is not set -# CONFIG_OPTIMIZATION_ASSERTIONS_DISABLED is not set -CONFIG_OPTIMIZATION_ASSERTION_LEVEL=2 -CONFIG_CXX_EXCEPTIONS=y -CONFIG_CXX_EXCEPTIONS_EMG_POOL_SIZE=0 -CONFIG_STACK_CHECK_NONE=y -# CONFIG_STACK_CHECK_NORM is not set -# CONFIG_STACK_CHECK_STRONG is not set -# CONFIG_STACK_CHECK_ALL is not set -# CONFIG_WARN_WRITE_STRINGS is not set -# CONFIG_DISABLE_GCC8_WARNINGS is not set -# CONFIG_ESP32_APPTRACE_DEST_TRAX is not set -CONFIG_ESP32_APPTRACE_DEST_NONE=y -CONFIG_ESP32_APPTRACE_LOCK_ENABLE=y -CONFIG_ADC2_DISABLE_DAC=y -CONFIG_DEFAULT_PSRAM_CLK_IO=30 -CONFIG_DEFAULT_PSRAM_CS_IO=26 -# CONFIG_EVENT_LOOP_PROFILING is not set -CONFIG_POST_EVENTS_FROM_ISR=y -CONFIG_POST_EVENTS_FROM_IRAM_ISR=y -CONFIG_ESP32C3_LIGHTSLEEP_GPIO_RESET_WORKAROUND=y -CONFIG_IPC_TASK_STACK_SIZE=1536 -CONFIG_ESP32_PHY_CALIBRATION_AND_DATA_STORAGE=y -# CONFIG_ESP32_PHY_INIT_DATA_IN_PARTITION is not set -CONFIG_ESP32_PHY_MAX_WIFI_TX_POWER=20 -CONFIG_ESP32_PHY_MAX_TX_POWER=20 -# CONFIG_ESP32_REDUCE_PHY_TX_POWER is not set -CONFIG_ESP_SYSTEM_PM_POWER_DOWN_CPU=y -# CONFIG_ESP32S2_PANIC_PRINT_HALT is not set -CONFIG_ESP32S2_PANIC_PRINT_REBOOT=y -# CONFIG_ESP32S2_PANIC_SILENT_REBOOT is not set -# CONFIG_ESP32S2_PANIC_GDBSTUB is not set -CONFIG_ESP32S2_ALLOW_RTC_FAST_MEM_AS_HEAP=y -CONFIG_SYSTEM_EVENT_QUEUE_SIZE=32 -CONFIG_SYSTEM_EVENT_TASK_STACK_SIZE=2304 -CONFIG_MAIN_TASK_STACK_SIZE=3584 -CONFIG_CONSOLE_UART_DEFAULT=y -# CONFIG_CONSOLE_UART_CUSTOM is not set -# CONFIG_ESP_CONSOLE_UART_NONE is not set -CONFIG_CONSOLE_UART=y -CONFIG_CONSOLE_UART_NUM=0 -CONFIG_CONSOLE_UART_BAUDRATE=115200 -CONFIG_INT_WDT=y -CONFIG_INT_WDT_TIMEOUT_MS=300 -CONFIG_INT_WDT_CHECK_CPU1=y -CONFIG_TASK_WDT=y -# CONFIG_TASK_WDT_PANIC is not set -CONFIG_TASK_WDT_TIMEOUT_S=5 -CONFIG_TASK_WDT_CHECK_IDLE_TASK_CPU0=y -CONFIG_TASK_WDT_CHECK_IDLE_TASK_CPU1=y -# CONFIG_ESP32_DEBUG_STUBS_ENABLE is not set -CONFIG_TIMER_TASK_STACK_SIZE=3584 -# CONFIG_ESP32_ENABLE_COREDUMP_TO_FLASH is not set -# CONFIG_ESP32_ENABLE_COREDUMP_TO_UART is not set -CONFIG_ESP32_ENABLE_COREDUMP_TO_NONE=y -CONFIG_MB_MASTER_TIMEOUT_MS_RESPOND=150 -CONFIG_MB_MASTER_DELAY_MS_CONVERT=200 -CONFIG_MB_QUEUE_LENGTH=20 -CONFIG_MB_SERIAL_TASK_STACK_SIZE=4096 -CONFIG_MB_SERIAL_BUF_SIZE=256 -CONFIG_MB_SERIAL_TASK_PRIO=10 -CONFIG_MB_CONTROLLER_SLAVE_ID_SUPPORT=y -CONFIG_MB_CONTROLLER_SLAVE_ID=0x00112233 -CONFIG_MB_CONTROLLER_NOTIFY_TIMEOUT=20 -CONFIG_MB_CONTROLLER_NOTIFY_QUEUE_SIZE=20 -CONFIG_MB_CONTROLLER_STACK_SIZE=4096 -CONFIG_MB_EVENT_QUEUE_TIMEOUT=20 -# CONFIG_MB_TIMER_PORT_ENABLED is not set -# CONFIG_ENABLE_STATIC_TASK_CLEAN_UP_HOOK is not set -CONFIG_TIMER_TASK_PRIORITY=1 -CONFIG_TIMER_TASK_STACK_DEPTH=3120 -CONFIG_TIMER_QUEUE_LENGTH=10 -# CONFIG_L2_TO_L3_COPY is not set -# CONFIG_USE_ONLY_LWIP_SELECT is not set -CONFIG_ESP_GRATUITOUS_ARP=y -CONFIG_GARP_TMR_INTERVAL=60 -CONFIG_TCPIP_RECVMBOX_SIZE=32 -CONFIG_TCP_MAXRTX=12 -CONFIG_TCP_SYNMAXRTX=12 -CONFIG_TCP_MSS=1440 -CONFIG_TCP_MSL=60000 -CONFIG_TCP_SND_BUF_DEFAULT=5760 -CONFIG_TCP_WND_DEFAULT=5760 -CONFIG_TCP_RECVMBOX_SIZE=6 -CONFIG_TCP_QUEUE_OOSEQ=y -# CONFIG_ESP_TCP_KEEP_CONNECTION_WHEN_IP_CHANGES is not set -CONFIG_TCP_OVERSIZE_MSS=y -# CONFIG_TCP_OVERSIZE_QUARTER_MSS is not set -# CONFIG_TCP_OVERSIZE_DISABLE is not set -CONFIG_UDP_RECVMBOX_SIZE=6 -CONFIG_TCPIP_TASK_STACK_SIZE=3072 -CONFIG_TCPIP_TASK_AFFINITY_NO_AFFINITY=y -# CONFIG_TCPIP_TASK_AFFINITY_CPU0 is not set -# CONFIG_TCPIP_TASK_AFFINITY_CPU1 is not set -CONFIG_TCPIP_TASK_AFFINITY=0x7FFFFFFF -# CONFIG_PPP_SUPPORT is not set -CONFIG_ESP32_PTHREAD_TASK_PRIO_DEFAULT=5 -CONFIG_ESP32_PTHREAD_TASK_STACK_SIZE_DEFAULT=3072 -CONFIG_ESP32_PTHREAD_STACK_MIN=768 -CONFIG_ESP32_DEFAULT_PTHREAD_CORE_NO_AFFINITY=y -# CONFIG_ESP32_DEFAULT_PTHREAD_CORE_0 is not set -# CONFIG_ESP32_DEFAULT_PTHREAD_CORE_1 is not set -CONFIG_ESP32_PTHREAD_TASK_CORE_DEFAULT=-1 -CONFIG_ESP32_PTHREAD_TASK_NAME_DEFAULT="pthread" -CONFIG_SPI_FLASH_WRITING_DANGEROUS_REGIONS_ABORTS=y -# CONFIG_SPI_FLASH_WRITING_DANGEROUS_REGIONS_FAILS is not set -# CONFIG_SPI_FLASH_WRITING_DANGEROUS_REGIONS_ALLOWED is not set -# CONFIG_USB_ENABLED is not set -CONFIG_SUPPRESS_SELECT_DEBUG_OUTPUT=y -CONFIG_SUPPORT_TERMIOS=y -CONFIG_SEMIHOSTFS_MAX_MOUNT_POINTS=1 -# End of deprecated options diff --git a/ci/Dockerfile b/ci/Dockerfile deleted file mode 100644 index 795d695..0000000 --- a/ci/Dockerfile +++ /dev/null @@ -1,15 +0,0 @@ -# Use the official Python 3.9 image as the base -FROM python:3.9-slim - -# Set the working directory -WORKDIR /workspace - -RUN apt-get update && apt-get install -y git - -# Install PlatformIO -RUN pip install platformio - -WORKDIR /usr/src - -CMD ["platformio", "run"] - diff --git a/data b/data index f5a9133..dcdf989 160000 --- a/data +++ b/data @@ -1 +1 @@ -Subproject commit f5a9133cabfbab82325275575545c12f7aacf8f2 +Subproject commit dcdf98964a42ccd83b2d2501bbed46a640bbc300 diff --git a/dependencies.lock b/dependencies.lock index 2274b85..c645bdf 100644 --- a/dependencies.lock +++ b/dependencies.lock @@ -3,7 +3,7 @@ dependencies: component_hash: null source: type: idf - version: 4.4.7 -manifest_hash: 1d4ef353a86901733b106a1897b186dbf9fc091a4981f0560ea2f6899b7a3d44 + version: 4.4.6 +manifest_hash: f4c10dfb616cf7e24f85cb263b8c89ef7d6d8eee64860fd27097b1a83ba56960 target: esp32s3 version: 1.0.0 diff --git a/include/timezone_data.hpp b/include/timezone_data.hpp deleted file mode 100644 index 1ebb5db..0000000 --- a/include/timezone_data.hpp +++ /dev/null @@ -1,721 +0,0 @@ -#pragma once - -#include -#include -#include - -namespace timezone_data { - -// Enum for unique timezone strings -enum class TimezoneValue : uint8_t { - plus000plus02_2M350_1M1050_3, - plus01_1, - plus02_2, - plus0330_330, - plus03_3, - plus0430_430, - plus04_4, - plus0530_530, - plus0545_545, - plus05_5, - plus0630_630, - plus06_6, - plus07_7, - plus0845_845, - plus08_8, - plus09_9, - plus1030_1030plus11_11M1010M410, - plus10_10, - plus11_11, - plus11_11plus12M1010M410_3, - plus1245_1245plus1345M950_245M410_345, - plus12_12, - plus13_13, - plus14_14, - _011, - _011plus00M350_0M1050_1, - _022, - _022_01M350__1M1050_0, - _033, - _033_02M320M1110, - _044, - _044_03M1010_0M340_0, - _044_03M916_24M416_24, - _055, - _066, - _066_05M916_22M416_22, - _077, - _088, - _0930930, - _099, - _1010, - _1111, - _1212, - ACST_930, - ACST_930ACDTM1010M410_3, - AEST_10, - AEST_10AEDTM1010M410_3, - AKST9AKDTM320M1110, - AST4, - AST4ADTM320M1110, - AWST_8, - CAT_2, - CET_1, - CET_1CESTM350M1050_3, - CST_8, - CST5CDTM320_0M1110_1, - CST6, - CST6CDTM320M1110, - ChST_10, - EAT_3, - EET_2, - EET_2EESTM344_50M1044_50, - EET_2EESTM350M1050_3, - EET_2EESTM350_0M1050_0, - EET_2EESTM350_3M1050_4, - EET_2EESTM455_0M1054_24, - EST5, - EST5EDTM320M1110, - GMT0, - GMT0BSTM350_1M1050, - HKT_8, - HST10, - HST10HDTM320M1110, - IST_1GMT0M1050M350_1, - IST_2IDTM344_26M1050, - IST_530, - JST_9, - KST_9, - MSK_3, - MST7, - MST7MDTM320M1110, - NST330NDTM320M1110, - NZST_12NZDTM950M410_3, - PKT_5, - PST_8, - PST8PDTM320M1110, - SAST_2, - SST11, - UTC0, - WAT_1, - WET0WESTM350_1M1050, - WIB_7, - WIT_9, - WITA_8, -}; - -// Key-value pair type -using TimezoneEntry = std::pair; - -// Lookup table -constexpr std::array TIMEZONE_DATA = {{ - {"Africa/Abidjan", TimezoneValue::GMT0}, - {"Africa/Accra", TimezoneValue::GMT0}, - {"Africa/Addis_Ababa", TimezoneValue::EAT_3}, - {"Africa/Algiers", TimezoneValue::CET_1}, - {"Africa/Asmara", TimezoneValue::EAT_3}, - {"Africa/Bamako", TimezoneValue::GMT0}, - {"Africa/Bangui", TimezoneValue::WAT_1}, - {"Africa/Banjul", TimezoneValue::GMT0}, - {"Africa/Bissau", TimezoneValue::GMT0}, - {"Africa/Blantyre", TimezoneValue::CAT_2}, - {"Africa/Brazzaville", TimezoneValue::WAT_1}, - {"Africa/Bujumbura", TimezoneValue::CAT_2}, - {"Africa/Cairo", TimezoneValue::EET_2EESTM455_0M1054_24}, - {"Africa/Casablanca", TimezoneValue::plus01_1}, - {"Africa/Ceuta", TimezoneValue::CET_1CESTM350M1050_3}, - {"Africa/Conakry", TimezoneValue::GMT0}, - {"Africa/Dakar", TimezoneValue::GMT0}, - {"Africa/Dar_es_Salaam", TimezoneValue::EAT_3}, - {"Africa/Djibouti", TimezoneValue::EAT_3}, - {"Africa/Douala", TimezoneValue::WAT_1}, - {"Africa/El_Aaiun", TimezoneValue::plus01_1}, - {"Africa/Freetown", TimezoneValue::GMT0}, - {"Africa/Gaborone", TimezoneValue::CAT_2}, - {"Africa/Harare", TimezoneValue::CAT_2}, - {"Africa/Johannesburg", TimezoneValue::SAST_2}, - {"Africa/Juba", TimezoneValue::CAT_2}, - {"Africa/Kampala", TimezoneValue::EAT_3}, - {"Africa/Khartoum", TimezoneValue::CAT_2}, - {"Africa/Kigali", TimezoneValue::CAT_2}, - {"Africa/Kinshasa", TimezoneValue::WAT_1}, - {"Africa/Lagos", TimezoneValue::WAT_1}, - {"Africa/Libreville", TimezoneValue::WAT_1}, - {"Africa/Lome", TimezoneValue::GMT0}, - {"Africa/Luanda", TimezoneValue::WAT_1}, - {"Africa/Lubumbashi", TimezoneValue::CAT_2}, - {"Africa/Lusaka", TimezoneValue::CAT_2}, - {"Africa/Malabo", TimezoneValue::WAT_1}, - {"Africa/Maputo", TimezoneValue::CAT_2}, - {"Africa/Maseru", TimezoneValue::SAST_2}, - {"Africa/Mbabane", TimezoneValue::SAST_2}, - {"Africa/Mogadishu", TimezoneValue::EAT_3}, - {"Africa/Monrovia", TimezoneValue::GMT0}, - {"Africa/Nairobi", TimezoneValue::EAT_3}, - {"Africa/Ndjamena", TimezoneValue::WAT_1}, - {"Africa/Niamey", TimezoneValue::WAT_1}, - {"Africa/Nouakchott", TimezoneValue::GMT0}, - {"Africa/Ouagadougou", TimezoneValue::GMT0}, - {"Africa/Porto-Novo", TimezoneValue::WAT_1}, - {"Africa/Sao_Tome", TimezoneValue::GMT0}, - {"Africa/Tripoli", TimezoneValue::EET_2}, - {"Africa/Tunis", TimezoneValue::CET_1}, - {"Africa/Windhoek", TimezoneValue::CAT_2}, - {"America/Adak", TimezoneValue::HST10HDTM320M1110}, - {"America/Anchorage", TimezoneValue::AKST9AKDTM320M1110}, - {"America/Anguilla", TimezoneValue::AST4}, - {"America/Antigua", TimezoneValue::AST4}, - {"America/Araguaina", TimezoneValue::_033}, - {"America/Argentina/Buenos_Aires", TimezoneValue::_033}, - {"America/Argentina/Catamarca", TimezoneValue::_033}, - {"America/Argentina/Cordoba", TimezoneValue::_033}, - {"America/Argentina/Jujuy", TimezoneValue::_033}, - {"America/Argentina/La_Rioja", TimezoneValue::_033}, - {"America/Argentina/Mendoza", TimezoneValue::_033}, - {"America/Argentina/Rio_Gallegos", TimezoneValue::_033}, - {"America/Argentina/Salta", TimezoneValue::_033}, - {"America/Argentina/San_Juan", TimezoneValue::_033}, - {"America/Argentina/San_Luis", TimezoneValue::_033}, - {"America/Argentina/Tucuman", TimezoneValue::_033}, - {"America/Argentina/Ushuaia", TimezoneValue::_033}, - {"America/Aruba", TimezoneValue::AST4}, - {"America/Asuncion", TimezoneValue::_044_03M1010_0M340_0}, - {"America/Atikokan", TimezoneValue::EST5}, - {"America/Bahia", TimezoneValue::_033}, - {"America/Bahia_Banderas", TimezoneValue::CST6}, - {"America/Barbados", TimezoneValue::AST4}, - {"America/Belem", TimezoneValue::_033}, - {"America/Belize", TimezoneValue::CST6}, - {"America/Blanc-Sablon", TimezoneValue::AST4}, - {"America/Boa_Vista", TimezoneValue::_044}, - {"America/Bogota", TimezoneValue::_055}, - {"America/Boise", TimezoneValue::MST7MDTM320M1110}, - {"America/Cambridge_Bay", TimezoneValue::MST7MDTM320M1110}, - {"America/Campo_Grande", TimezoneValue::_044}, - {"America/Cancun", TimezoneValue::EST5}, - {"America/Caracas", TimezoneValue::_044}, - {"America/Cayenne", TimezoneValue::_033}, - {"America/Cayman", TimezoneValue::EST5}, - {"America/Chicago", TimezoneValue::CST6CDTM320M1110}, - {"America/Chihuahua", TimezoneValue::CST6}, - {"America/Costa_Rica", TimezoneValue::CST6}, - {"America/Creston", TimezoneValue::MST7}, - {"America/Cuiaba", TimezoneValue::_044}, - {"America/Curacao", TimezoneValue::AST4}, - {"America/Danmarkshavn", TimezoneValue::GMT0}, - {"America/Dawson", TimezoneValue::MST7}, - {"America/Dawson_Creek", TimezoneValue::MST7}, - {"America/Denver", TimezoneValue::MST7MDTM320M1110}, - {"America/Detroit", TimezoneValue::EST5EDTM320M1110}, - {"America/Dominica", TimezoneValue::AST4}, - {"America/Edmonton", TimezoneValue::MST7MDTM320M1110}, - {"America/Eirunepe", TimezoneValue::_055}, - {"America/El_Salvador", TimezoneValue::CST6}, - {"America/Fort_Nelson", TimezoneValue::MST7}, - {"America/Fortaleza", TimezoneValue::_033}, - {"America/Glace_Bay", TimezoneValue::AST4ADTM320M1110}, - {"America/Godthab", TimezoneValue::_022_01M350__1M1050_0}, - {"America/Goose_Bay", TimezoneValue::AST4ADTM320M1110}, - {"America/Grand_Turk", TimezoneValue::EST5EDTM320M1110}, - {"America/Grenada", TimezoneValue::AST4}, - {"America/Guadeloupe", TimezoneValue::AST4}, - {"America/Guatemala", TimezoneValue::CST6}, - {"America/Guayaquil", TimezoneValue::_055}, - {"America/Guyana", TimezoneValue::_044}, - {"America/Halifax", TimezoneValue::AST4ADTM320M1110}, - {"America/Havana", TimezoneValue::CST5CDTM320_0M1110_1}, - {"America/Hermosillo", TimezoneValue::MST7}, - {"America/Indiana/Indianapolis", TimezoneValue::EST5EDTM320M1110}, - {"America/Indiana/Knox", TimezoneValue::CST6CDTM320M1110}, - {"America/Indiana/Marengo", TimezoneValue::EST5EDTM320M1110}, - {"America/Indiana/Petersburg", TimezoneValue::EST5EDTM320M1110}, - {"America/Indiana/Tell_City", TimezoneValue::CST6CDTM320M1110}, - {"America/Indiana/Vevay", TimezoneValue::EST5EDTM320M1110}, - {"America/Indiana/Vincennes", TimezoneValue::EST5EDTM320M1110}, - {"America/Indiana/Winamac", TimezoneValue::EST5EDTM320M1110}, - {"America/Inuvik", TimezoneValue::MST7MDTM320M1110}, - {"America/Iqaluit", TimezoneValue::EST5EDTM320M1110}, - {"America/Jamaica", TimezoneValue::EST5}, - {"America/Juneau", TimezoneValue::AKST9AKDTM320M1110}, - {"America/Kentucky/Louisville", TimezoneValue::EST5EDTM320M1110}, - {"America/Kentucky/Monticello", TimezoneValue::EST5EDTM320M1110}, - {"America/Kralendijk", TimezoneValue::AST4}, - {"America/La_Paz", TimezoneValue::_044}, - {"America/Lima", TimezoneValue::_055}, - {"America/Los_Angeles", TimezoneValue::PST8PDTM320M1110}, - {"America/Lower_Princes", TimezoneValue::AST4}, - {"America/Maceio", TimezoneValue::_033}, - {"America/Managua", TimezoneValue::CST6}, - {"America/Manaus", TimezoneValue::_044}, - {"America/Marigot", TimezoneValue::AST4}, - {"America/Martinique", TimezoneValue::AST4}, - {"America/Matamoros", TimezoneValue::CST6CDTM320M1110}, - {"America/Mazatlan", TimezoneValue::MST7}, - {"America/Menominee", TimezoneValue::CST6CDTM320M1110}, - {"America/Merida", TimezoneValue::CST6}, - {"America/Metlakatla", TimezoneValue::AKST9AKDTM320M1110}, - {"America/Mexico_City", TimezoneValue::CST6}, - {"America/Miquelon", TimezoneValue::_033_02M320M1110}, - {"America/Moncton", TimezoneValue::AST4ADTM320M1110}, - {"America/Monterrey", TimezoneValue::CST6}, - {"America/Montevideo", TimezoneValue::_033}, - {"America/Montreal", TimezoneValue::EST5EDTM320M1110}, - {"America/Montserrat", TimezoneValue::AST4}, - {"America/Nassau", TimezoneValue::EST5EDTM320M1110}, - {"America/New_York", TimezoneValue::EST5EDTM320M1110}, - {"America/Nipigon", TimezoneValue::EST5EDTM320M1110}, - {"America/Nome", TimezoneValue::AKST9AKDTM320M1110}, - {"America/Noronha", TimezoneValue::_022}, - {"America/North_Dakota/Beulah", TimezoneValue::CST6CDTM320M1110}, - {"America/North_Dakota/Center", TimezoneValue::CST6CDTM320M1110}, - {"America/North_Dakota/New_Salem", TimezoneValue::CST6CDTM320M1110}, - {"America/Nuuk", TimezoneValue::_022_01M350__1M1050_0}, - {"America/Ojinaga", TimezoneValue::CST6CDTM320M1110}, - {"America/Panama", TimezoneValue::EST5}, - {"America/Pangnirtung", TimezoneValue::EST5EDTM320M1110}, - {"America/Paramaribo", TimezoneValue::_033}, - {"America/Phoenix", TimezoneValue::MST7}, - {"America/Port-au-Prince", TimezoneValue::EST5EDTM320M1110}, - {"America/Port_of_Spain", TimezoneValue::AST4}, - {"America/Porto_Velho", TimezoneValue::_044}, - {"America/Puerto_Rico", TimezoneValue::AST4}, - {"America/Punta_Arenas", TimezoneValue::_033}, - {"America/Rainy_River", TimezoneValue::CST6CDTM320M1110}, - {"America/Rankin_Inlet", TimezoneValue::CST6CDTM320M1110}, - {"America/Recife", TimezoneValue::_033}, - {"America/Regina", TimezoneValue::CST6}, - {"America/Resolute", TimezoneValue::CST6CDTM320M1110}, - {"America/Rio_Branco", TimezoneValue::_055}, - {"America/Santarem", TimezoneValue::_033}, - {"America/Santiago", TimezoneValue::_044_03M916_24M416_24}, - {"America/Santo_Domingo", TimezoneValue::AST4}, - {"America/Sao_Paulo", TimezoneValue::_033}, - {"America/Scoresbysund", TimezoneValue::_022_01M350__1M1050_0}, - {"America/Sitka", TimezoneValue::AKST9AKDTM320M1110}, - {"America/St_Barthelemy", TimezoneValue::AST4}, - {"America/St_Johns", TimezoneValue::NST330NDTM320M1110}, - {"America/St_Kitts", TimezoneValue::AST4}, - {"America/St_Lucia", TimezoneValue::AST4}, - {"America/St_Thomas", TimezoneValue::AST4}, - {"America/St_Vincent", TimezoneValue::AST4}, - {"America/Swift_Current", TimezoneValue::CST6}, - {"America/Tegucigalpa", TimezoneValue::CST6}, - {"America/Thule", TimezoneValue::AST4ADTM320M1110}, - {"America/Thunder_Bay", TimezoneValue::EST5EDTM320M1110}, - {"America/Tijuana", TimezoneValue::PST8PDTM320M1110}, - {"America/Toronto", TimezoneValue::EST5EDTM320M1110}, - {"America/Tortola", TimezoneValue::AST4}, - {"America/Vancouver", TimezoneValue::PST8PDTM320M1110}, - {"America/Whitehorse", TimezoneValue::MST7}, - {"America/Winnipeg", TimezoneValue::CST6CDTM320M1110}, - {"America/Yakutat", TimezoneValue::AKST9AKDTM320M1110}, - {"America/Yellowknife", TimezoneValue::MST7MDTM320M1110}, - {"Antarctica/Casey", TimezoneValue::plus08_8}, - {"Antarctica/Davis", TimezoneValue::plus07_7}, - {"Antarctica/DumontDUrville", TimezoneValue::plus10_10}, - {"Antarctica/Macquarie", TimezoneValue::AEST_10AEDTM1010M410_3}, - {"Antarctica/Mawson", TimezoneValue::plus05_5}, - {"Antarctica/McMurdo", TimezoneValue::NZST_12NZDTM950M410_3}, - {"Antarctica/Palmer", TimezoneValue::_033}, - {"Antarctica/Rothera", TimezoneValue::_033}, - {"Antarctica/Syowa", TimezoneValue::plus03_3}, - {"Antarctica/Troll", TimezoneValue::plus000plus02_2M350_1M1050_3}, - {"Antarctica/Vostok", TimezoneValue::plus05_5}, - {"Arctic/Longyearbyen", TimezoneValue::CET_1CESTM350M1050_3}, - {"Asia/Aden", TimezoneValue::plus03_3}, - {"Asia/Almaty", TimezoneValue::plus05_5}, - {"Asia/Amman", TimezoneValue::plus03_3}, - {"Asia/Anadyr", TimezoneValue::plus12_12}, - {"Asia/Aqtau", TimezoneValue::plus05_5}, - {"Asia/Aqtobe", TimezoneValue::plus05_5}, - {"Asia/Ashgabat", TimezoneValue::plus05_5}, - {"Asia/Atyrau", TimezoneValue::plus05_5}, - {"Asia/Baghdad", TimezoneValue::plus03_3}, - {"Asia/Bahrain", TimezoneValue::plus03_3}, - {"Asia/Baku", TimezoneValue::plus04_4}, - {"Asia/Bangkok", TimezoneValue::plus07_7}, - {"Asia/Barnaul", TimezoneValue::plus07_7}, - {"Asia/Beirut", TimezoneValue::EET_2EESTM350_0M1050_0}, - {"Asia/Bishkek", TimezoneValue::plus06_6}, - {"Asia/Brunei", TimezoneValue::plus08_8}, - {"Asia/Chita", TimezoneValue::plus09_9}, - {"Asia/Choibalsan", TimezoneValue::plus08_8}, - {"Asia/Colombo", TimezoneValue::plus0530_530}, - {"Asia/Damascus", TimezoneValue::plus03_3}, - {"Asia/Dhaka", TimezoneValue::plus06_6}, - {"Asia/Dili", TimezoneValue::plus09_9}, - {"Asia/Dubai", TimezoneValue::plus04_4}, - {"Asia/Dushanbe", TimezoneValue::plus05_5}, - {"Asia/Famagusta", TimezoneValue::EET_2EESTM350_3M1050_4}, - {"Asia/Gaza", TimezoneValue::EET_2EESTM344_50M1044_50}, - {"Asia/Hebron", TimezoneValue::EET_2EESTM344_50M1044_50}, - {"Asia/Ho_Chi_Minh", TimezoneValue::plus07_7}, - {"Asia/Hong_Kong", TimezoneValue::HKT_8}, - {"Asia/Hovd", TimezoneValue::plus07_7}, - {"Asia/Irkutsk", TimezoneValue::plus08_8}, - {"Asia/Jakarta", TimezoneValue::WIB_7}, - {"Asia/Jayapura", TimezoneValue::WIT_9}, - {"Asia/Jerusalem", TimezoneValue::IST_2IDTM344_26M1050}, - {"Asia/Kabul", TimezoneValue::plus0430_430}, - {"Asia/Kamchatka", TimezoneValue::plus12_12}, - {"Asia/Karachi", TimezoneValue::PKT_5}, - {"Asia/Kathmandu", TimezoneValue::plus0545_545}, - {"Asia/Khandyga", TimezoneValue::plus09_9}, - {"Asia/Kolkata", TimezoneValue::IST_530}, - {"Asia/Krasnoyarsk", TimezoneValue::plus07_7}, - {"Asia/Kuala_Lumpur", TimezoneValue::plus08_8}, - {"Asia/Kuching", TimezoneValue::plus08_8}, - {"Asia/Kuwait", TimezoneValue::plus03_3}, - {"Asia/Macau", TimezoneValue::CST_8}, - {"Asia/Magadan", TimezoneValue::plus11_11}, - {"Asia/Makassar", TimezoneValue::WITA_8}, - {"Asia/Manila", TimezoneValue::PST_8}, - {"Asia/Muscat", TimezoneValue::plus04_4}, - {"Asia/Nicosia", TimezoneValue::EET_2EESTM350_3M1050_4}, - {"Asia/Novokuznetsk", TimezoneValue::plus07_7}, - {"Asia/Novosibirsk", TimezoneValue::plus07_7}, - {"Asia/Omsk", TimezoneValue::plus06_6}, - {"Asia/Oral", TimezoneValue::plus05_5}, - {"Asia/Phnom_Penh", TimezoneValue::plus07_7}, - {"Asia/Pontianak", TimezoneValue::WIB_7}, - {"Asia/Pyongyang", TimezoneValue::KST_9}, - {"Asia/Qatar", TimezoneValue::plus03_3}, - {"Asia/Qyzylorda", TimezoneValue::plus05_5}, - {"Asia/Riyadh", TimezoneValue::plus03_3}, - {"Asia/Sakhalin", TimezoneValue::plus11_11}, - {"Asia/Samarkand", TimezoneValue::plus05_5}, - {"Asia/Seoul", TimezoneValue::KST_9}, - {"Asia/Shanghai", TimezoneValue::CST_8}, - {"Asia/Singapore", TimezoneValue::plus08_8}, - {"Asia/Srednekolymsk", TimezoneValue::plus11_11}, - {"Asia/Taipei", TimezoneValue::CST_8}, - {"Asia/Tashkent", TimezoneValue::plus05_5}, - {"Asia/Tbilisi", TimezoneValue::plus04_4}, - {"Asia/Tehran", TimezoneValue::plus0330_330}, - {"Asia/Thimphu", TimezoneValue::plus06_6}, - {"Asia/Tokyo", TimezoneValue::JST_9}, - {"Asia/Tomsk", TimezoneValue::plus07_7}, - {"Asia/Ulaanbaatar", TimezoneValue::plus08_8}, - {"Asia/Urumqi", TimezoneValue::plus06_6}, - {"Asia/Ust-Nera", TimezoneValue::plus10_10}, - {"Asia/Vientiane", TimezoneValue::plus07_7}, - {"Asia/Vladivostok", TimezoneValue::plus10_10}, - {"Asia/Yakutsk", TimezoneValue::plus09_9}, - {"Asia/Yangon", TimezoneValue::plus0630_630}, - {"Asia/Yekaterinburg", TimezoneValue::plus05_5}, - {"Asia/Yerevan", TimezoneValue::plus04_4}, - {"Atlantic/Azores", TimezoneValue::_011plus00M350_0M1050_1}, - {"Atlantic/Bermuda", TimezoneValue::AST4ADTM320M1110}, - {"Atlantic/Canary", TimezoneValue::WET0WESTM350_1M1050}, - {"Atlantic/Cape_Verde", TimezoneValue::_011}, - {"Atlantic/Faroe", TimezoneValue::WET0WESTM350_1M1050}, - {"Atlantic/Madeira", TimezoneValue::WET0WESTM350_1M1050}, - {"Atlantic/Reykjavik", TimezoneValue::GMT0}, - {"Atlantic/South_Georgia", TimezoneValue::_022}, - {"Atlantic/St_Helena", TimezoneValue::GMT0}, - {"Atlantic/Stanley", TimezoneValue::_033}, - {"Australia/Adelaide", TimezoneValue::ACST_930ACDTM1010M410_3}, - {"Australia/Brisbane", TimezoneValue::AEST_10}, - {"Australia/Broken_Hill", TimezoneValue::ACST_930ACDTM1010M410_3}, - {"Australia/Currie", TimezoneValue::AEST_10AEDTM1010M410_3}, - {"Australia/Darwin", TimezoneValue::ACST_930}, - {"Australia/Eucla", TimezoneValue::plus0845_845}, - {"Australia/Hobart", TimezoneValue::AEST_10AEDTM1010M410_3}, - {"Australia/Lindeman", TimezoneValue::AEST_10}, - {"Australia/Lord_Howe", TimezoneValue::plus1030_1030plus11_11M1010M410}, - {"Australia/Melbourne", TimezoneValue::AEST_10AEDTM1010M410_3}, - {"Australia/Perth", TimezoneValue::AWST_8}, - {"Australia/Sydney", TimezoneValue::AEST_10AEDTM1010M410_3}, - {"Etc/GMT", TimezoneValue::GMT0}, - {"Etc/GMT+0", TimezoneValue::GMT0}, - {"Etc/GMT+1", TimezoneValue::_011}, - {"Etc/GMT+10", TimezoneValue::_1010}, - {"Etc/GMT+11", TimezoneValue::_1111}, - {"Etc/GMT+12", TimezoneValue::_1212}, - {"Etc/GMT+2", TimezoneValue::_022}, - {"Etc/GMT+3", TimezoneValue::_033}, - {"Etc/GMT+4", TimezoneValue::_044}, - {"Etc/GMT+5", TimezoneValue::_055}, - {"Etc/GMT+6", TimezoneValue::_066}, - {"Etc/GMT+7", TimezoneValue::_077}, - {"Etc/GMT+8", TimezoneValue::_088}, - {"Etc/GMT+9", TimezoneValue::_099}, - {"Etc/GMT-0", TimezoneValue::GMT0}, - {"Etc/GMT-1", TimezoneValue::plus01_1}, - {"Etc/GMT-10", TimezoneValue::plus10_10}, - {"Etc/GMT-11", TimezoneValue::plus11_11}, - {"Etc/GMT-12", TimezoneValue::plus12_12}, - {"Etc/GMT-13", TimezoneValue::plus13_13}, - {"Etc/GMT-14", TimezoneValue::plus14_14}, - {"Etc/GMT-2", TimezoneValue::plus02_2}, - {"Etc/GMT-3", TimezoneValue::plus03_3}, - {"Etc/GMT-4", TimezoneValue::plus04_4}, - {"Etc/GMT-5", TimezoneValue::plus05_5}, - {"Etc/GMT-6", TimezoneValue::plus06_6}, - {"Etc/GMT-7", TimezoneValue::plus07_7}, - {"Etc/GMT-8", TimezoneValue::plus08_8}, - {"Etc/GMT-9", TimezoneValue::plus09_9}, - {"Etc/GMT0", TimezoneValue::GMT0}, - {"Etc/Greenwich", TimezoneValue::GMT0}, - {"Etc/UCT", TimezoneValue::UTC0}, - {"Etc/UTC", TimezoneValue::UTC0}, - {"Etc/Universal", TimezoneValue::UTC0}, - {"Etc/Zulu", TimezoneValue::UTC0}, - {"Europe/Amsterdam", TimezoneValue::CET_1CESTM350M1050_3}, - {"Europe/Andorra", TimezoneValue::CET_1CESTM350M1050_3}, - {"Europe/Astrakhan", TimezoneValue::plus04_4}, - {"Europe/Athens", TimezoneValue::EET_2EESTM350_3M1050_4}, - {"Europe/Belgrade", TimezoneValue::CET_1CESTM350M1050_3}, - {"Europe/Berlin", TimezoneValue::CET_1CESTM350M1050_3}, - {"Europe/Bratislava", TimezoneValue::CET_1CESTM350M1050_3}, - {"Europe/Brussels", TimezoneValue::CET_1CESTM350M1050_3}, - {"Europe/Bucharest", TimezoneValue::EET_2EESTM350_3M1050_4}, - {"Europe/Budapest", TimezoneValue::CET_1CESTM350M1050_3}, - {"Europe/Busingen", TimezoneValue::CET_1CESTM350M1050_3}, - {"Europe/Chisinau", TimezoneValue::EET_2EESTM350M1050_3}, - {"Europe/Copenhagen", TimezoneValue::CET_1CESTM350M1050_3}, - {"Europe/Dublin", TimezoneValue::IST_1GMT0M1050M350_1}, - {"Europe/Gibraltar", TimezoneValue::CET_1CESTM350M1050_3}, - {"Europe/Guernsey", TimezoneValue::GMT0BSTM350_1M1050}, - {"Europe/Helsinki", TimezoneValue::EET_2EESTM350_3M1050_4}, - {"Europe/Isle_of_Man", TimezoneValue::GMT0BSTM350_1M1050}, - {"Europe/Istanbul", TimezoneValue::plus03_3}, - {"Europe/Jersey", TimezoneValue::GMT0BSTM350_1M1050}, - {"Europe/Kaliningrad", TimezoneValue::EET_2}, - {"Europe/Kiev", TimezoneValue::EET_2EESTM350_3M1050_4}, - {"Europe/Kirov", TimezoneValue::MSK_3}, - {"Europe/Lisbon", TimezoneValue::WET0WESTM350_1M1050}, - {"Europe/Ljubljana", TimezoneValue::CET_1CESTM350M1050_3}, - {"Europe/London", TimezoneValue::GMT0BSTM350_1M1050}, - {"Europe/Luxembourg", TimezoneValue::CET_1CESTM350M1050_3}, - {"Europe/Madrid", TimezoneValue::CET_1CESTM350M1050_3}, - {"Europe/Malta", TimezoneValue::CET_1CESTM350M1050_3}, - {"Europe/Mariehamn", TimezoneValue::EET_2EESTM350_3M1050_4}, - {"Europe/Minsk", TimezoneValue::plus03_3}, - {"Europe/Monaco", TimezoneValue::CET_1CESTM350M1050_3}, - {"Europe/Moscow", TimezoneValue::MSK_3}, - {"Europe/Oslo", TimezoneValue::CET_1CESTM350M1050_3}, - {"Europe/Paris", TimezoneValue::CET_1CESTM350M1050_3}, - {"Europe/Podgorica", TimezoneValue::CET_1CESTM350M1050_3}, - {"Europe/Prague", TimezoneValue::CET_1CESTM350M1050_3}, - {"Europe/Riga", TimezoneValue::EET_2EESTM350_3M1050_4}, - {"Europe/Rome", TimezoneValue::CET_1CESTM350M1050_3}, - {"Europe/Samara", TimezoneValue::plus04_4}, - {"Europe/San_Marino", TimezoneValue::CET_1CESTM350M1050_3}, - {"Europe/Sarajevo", TimezoneValue::CET_1CESTM350M1050_3}, - {"Europe/Saratov", TimezoneValue::plus04_4}, - {"Europe/Simferopol", TimezoneValue::MSK_3}, - {"Europe/Skopje", TimezoneValue::CET_1CESTM350M1050_3}, - {"Europe/Sofia", TimezoneValue::EET_2EESTM350_3M1050_4}, - {"Europe/Stockholm", TimezoneValue::CET_1CESTM350M1050_3}, - {"Europe/Tallinn", TimezoneValue::EET_2EESTM350_3M1050_4}, - {"Europe/Tirane", TimezoneValue::CET_1CESTM350M1050_3}, - {"Europe/Ulyanovsk", TimezoneValue::plus04_4}, - {"Europe/Uzhgorod", TimezoneValue::EET_2EESTM350_3M1050_4}, - {"Europe/Vaduz", TimezoneValue::CET_1CESTM350M1050_3}, - {"Europe/Vatican", TimezoneValue::CET_1CESTM350M1050_3}, - {"Europe/Vienna", TimezoneValue::CET_1CESTM350M1050_3}, - {"Europe/Vilnius", TimezoneValue::EET_2EESTM350_3M1050_4}, - {"Europe/Volgograd", TimezoneValue::MSK_3}, - {"Europe/Warsaw", TimezoneValue::CET_1CESTM350M1050_3}, - {"Europe/Zagreb", TimezoneValue::CET_1CESTM350M1050_3}, - {"Europe/Zaporozhye", TimezoneValue::EET_2EESTM350_3M1050_4}, - {"Europe/Zurich", TimezoneValue::CET_1CESTM350M1050_3}, - {"Indian/Antananarivo", TimezoneValue::EAT_3}, - {"Indian/Chagos", TimezoneValue::plus06_6}, - {"Indian/Christmas", TimezoneValue::plus07_7}, - {"Indian/Cocos", TimezoneValue::plus0630_630}, - {"Indian/Comoro", TimezoneValue::EAT_3}, - {"Indian/Kerguelen", TimezoneValue::plus05_5}, - {"Indian/Mahe", TimezoneValue::plus04_4}, - {"Indian/Maldives", TimezoneValue::plus05_5}, - {"Indian/Mauritius", TimezoneValue::plus04_4}, - {"Indian/Mayotte", TimezoneValue::EAT_3}, - {"Indian/Reunion", TimezoneValue::plus04_4}, - {"Pacific/Apia", TimezoneValue::plus13_13}, - {"Pacific/Auckland", TimezoneValue::NZST_12NZDTM950M410_3}, - {"Pacific/Bougainville", TimezoneValue::plus11_11}, - {"Pacific/Chatham", TimezoneValue::plus1245_1245plus1345M950_245M410_345}, - {"Pacific/Chuuk", TimezoneValue::plus10_10}, - {"Pacific/Easter", TimezoneValue::_066_05M916_22M416_22}, - {"Pacific/Efate", TimezoneValue::plus11_11}, - {"Pacific/Enderbury", TimezoneValue::plus13_13}, - {"Pacific/Fakaofo", TimezoneValue::plus13_13}, - {"Pacific/Fiji", TimezoneValue::plus12_12}, - {"Pacific/Funafuti", TimezoneValue::plus12_12}, - {"Pacific/Galapagos", TimezoneValue::_066}, - {"Pacific/Gambier", TimezoneValue::_099}, - {"Pacific/Guadalcanal", TimezoneValue::plus11_11}, - {"Pacific/Guam", TimezoneValue::ChST_10}, - {"Pacific/Honolulu", TimezoneValue::HST10}, - {"Pacific/Kiritimati", TimezoneValue::plus14_14}, - {"Pacific/Kosrae", TimezoneValue::plus11_11}, - {"Pacific/Kwajalein", TimezoneValue::plus12_12}, - {"Pacific/Majuro", TimezoneValue::plus12_12}, - {"Pacific/Marquesas", TimezoneValue::_0930930}, - {"Pacific/Midway", TimezoneValue::SST11}, - {"Pacific/Nauru", TimezoneValue::plus12_12}, - {"Pacific/Niue", TimezoneValue::_1111}, - {"Pacific/Norfolk", TimezoneValue::plus11_11plus12M1010M410_3}, - {"Pacific/Noumea", TimezoneValue::plus11_11}, - {"Pacific/Pago_Pago", TimezoneValue::SST11}, - {"Pacific/Palau", TimezoneValue::plus09_9}, - {"Pacific/Pitcairn", TimezoneValue::_088}, - {"Pacific/Pohnpei", TimezoneValue::plus11_11}, - {"Pacific/Port_Moresby", TimezoneValue::plus10_10}, - {"Pacific/Rarotonga", TimezoneValue::_1010}, - {"Pacific/Saipan", TimezoneValue::ChST_10}, - {"Pacific/Tahiti", TimezoneValue::_1010}, - {"Pacific/Tarawa", TimezoneValue::plus12_12}, - {"Pacific/Tongatapu", TimezoneValue::plus13_13}, - {"Pacific/Wake", TimezoneValue::plus12_12}, - {"Pacific/Wallis", TimezoneValue::plus12_12}, -}}; - -// Helper function to find timezone value -inline TimezoneValue find_timezone_value(std::string_view key) { - for (const auto& entry : TIMEZONE_DATA) { - if (entry.first == key) { - return entry.second; - } - } - return TimezoneValue::plus000plus02_2M350_1M1050_3; // Default fallback -} - -// Overload for String -inline TimezoneValue find_timezone_value(const String& key) { - return find_timezone_value(std::string_view(key.c_str())); -} - -// Overload for std::string -inline TimezoneValue find_timezone_value(const std::string& key) { - return find_timezone_value(std::string_view(key)); -} - -// Helper function to convert TimezoneValue to string representation -inline String get_timezone_string(TimezoneValue value) { - for (const auto& entry : TIMEZONE_DATA) { - if (entry.second == value) { - return String(entry.first.data(), entry.first.length()); - } - } - return String("GMT0"); // Default fallback -} - -// Overload for std::string -inline std::string get_timezone_string_std(TimezoneValue value) { - for (const auto& entry : TIMEZONE_DATA) { - if (entry.second == value) { - return std::string(entry.first.data(), entry.first.length()); - } - } - return "GMT0"; // Default fallback -} - -// Helper function to convert TimezoneValue enum to its string representation -inline String get_timezone_value_string(TimezoneValue value) { - switch (value) { - case TimezoneValue::plus000plus02_2M350_1M1050_3: return String("+00:00+02:00,M3.5.0/1,M10.5.0/3"); - case TimezoneValue::plus01_1: return String("+01:00"); - case TimezoneValue::plus02_2: return String("+02:00"); - case TimezoneValue::plus0330_330: return String("+03:30"); - case TimezoneValue::plus03_3: return String("+03:00"); - case TimezoneValue::plus0430_430: return String("+04:30"); - case TimezoneValue::plus04_4: return String("+04:00"); - case TimezoneValue::plus0530_530: return String("+05:30"); - case TimezoneValue::plus0545_545: return String("+05:45"); - case TimezoneValue::plus05_5: return String("+05:00"); - case TimezoneValue::plus0630_630: return String("+06:30"); - case TimezoneValue::plus06_6: return String("+06:00"); - case TimezoneValue::plus07_7: return String("+07:00"); - case TimezoneValue::plus0845_845: return String("+08:45"); - case TimezoneValue::plus08_8: return String("+08:00"); - case TimezoneValue::plus09_9: return String("+09:00"); - case TimezoneValue::plus1030_1030plus11_11M1010M410: return String("+10:30+11:00,M10.1.0,M4.1.0"); - case TimezoneValue::plus10_10: return String("+10:00"); - case TimezoneValue::plus11_11: return String("+11:00"); - case TimezoneValue::plus11_11plus12M1010M410_3: return String("+11:00+12:00,M10.1.0,M4.1.0/3"); - case TimezoneValue::plus1245_1245plus1345M950_245M410_345: return String("+12:45+13:45,M9.5.0/2:45,M4.1.0/3:45"); - case TimezoneValue::plus12_12: return String("+12:00"); - case TimezoneValue::plus13_13: return String("+13:00"); - case TimezoneValue::plus14_14: return String("+14:00"); - case TimezoneValue::_011: return String("-01:00"); - case TimezoneValue::_011plus00M350_0M1050_1: return String("-01:00+00:00,M3.5.0/0,M10.5.0/1"); - case TimezoneValue::_022: return String("-02:00"); - case TimezoneValue::_022_01M350__1M1050_0: return String("-02:00-01:00,M3.5.0/-1,M10.5.0/0"); - case TimezoneValue::_033: return String("-03:00"); - case TimezoneValue::_033_02M320M1110: return String("-03:00-02:00,M3.2.0,M11.1.0"); - case TimezoneValue::_044: return String("-04:00"); - case TimezoneValue::_044_03M1010_0M340_0: return String("-04:00-03:00,M10.1.0/0,M3.4.0/0"); - case TimezoneValue::_044_03M916_24M416_24: return String("-04:00-03:00,M9.1.6/24,M4.1.6/24"); - case TimezoneValue::_055: return String("-05:00"); - case TimezoneValue::_066: return String("-06:00"); - case TimezoneValue::_066_05M916_22M416_22: return String("-06:00-05:00,M9.1.6/22,M4.1.6/22"); - case TimezoneValue::_077: return String("-07:00"); - case TimezoneValue::_088: return String("-08:00"); - case TimezoneValue::_0930930: return String("-09:30"); - case TimezoneValue::_099: return String("-09:00"); - case TimezoneValue::_1010: return String("-10:00"); - case TimezoneValue::_1111: return String("-11:00"); - case TimezoneValue::_1212: return String("-12:00"); - case TimezoneValue::ACST_930: return String("ACST-9:30"); - case TimezoneValue::ACST_930ACDTM1010M410_3: return String("ACST-9:30ACDT,M10.1.0,M4.1.0/3"); - case TimezoneValue::AEST_10: return String("AEST-10"); - case TimezoneValue::AEST_10AEDTM1010M410_3: return String("AEST-10AEDT,M10.1.0,M4.1.0/3"); - case TimezoneValue::AKST9AKDTM320M1110: return String("AKST9AKDT,M3.2.0,M11.1.0"); - case TimezoneValue::AST4: return String("AST4"); - case TimezoneValue::AST4ADTM320M1110: return String("AST4ADT,M3.2.0,M11.1.0"); - case TimezoneValue::AWST_8: return String("AWST-8"); - case TimezoneValue::CAT_2: return String("CAT-2"); - case TimezoneValue::CET_1: return String("CET-1"); - case TimezoneValue::CET_1CESTM350M1050_3: return String("CET-1CEST,M3.5.0,M10.5.0/3"); - case TimezoneValue::CST_8: return String("CST-8"); - case TimezoneValue::CST5CDTM320_0M1110_1: return String("CST5CDT,M3.2.0/0,M11.1.0/1"); - case TimezoneValue::CST6: return String("CST6"); - case TimezoneValue::CST6CDTM320M1110: return String("CST6CDT,M3.2.0,M11.1.0"); - case TimezoneValue::ChST_10: return String("ChST-10"); - case TimezoneValue::EAT_3: return String("EAT-3"); - case TimezoneValue::EET_2: return String("EET-2"); - case TimezoneValue::EET_2EESTM344_50M1044_50: return String("EET-2EEST,M3.4.4/50,M10.4.4/50"); - case TimezoneValue::EET_2EESTM350M1050_3: return String("EET-2EEST,M3.5.0,M10.5.0/3"); - case TimezoneValue::EET_2EESTM350_0M1050_0: return String("EET-2EEST,M3.5.0/0,M10.5.0/0"); - case TimezoneValue::EET_2EESTM350_3M1050_4: return String("EET-2EEST,M3.5.0/3,M10.5.0/4"); - case TimezoneValue::EET_2EESTM455_0M1054_24: return String("EET-2EEST,M4.5.5/0,M10.5.4/24"); - case TimezoneValue::EST5: return String("EST5"); - case TimezoneValue::EST5EDTM320M1110: return String("EST5EDT,M3.2.0,M11.1.0"); - case TimezoneValue::GMT0: return String("GMT0"); - case TimezoneValue::GMT0BSTM350_1M1050: return String("GMT0BST,M3.5.0/1,M10.5.0"); - case TimezoneValue::HKT_8: return String("HKT-8"); - case TimezoneValue::HST10: return String("HST10"); - case TimezoneValue::HST10HDTM320M1110: return String("HST10HDT,M3.2.0,M11.1.0"); - case TimezoneValue::IST_1GMT0M1050M350_1: return String("IST-1GMT0,M10.5.0,M3.5.0/1"); - case TimezoneValue::IST_2IDTM344_26M1050: return String("IST-2IDT,M3.4.4/26,M10.5.0"); - case TimezoneValue::IST_530: return String("IST-5:30"); - case TimezoneValue::JST_9: return String("JST-9"); - case TimezoneValue::KST_9: return String("KST-9"); - case TimezoneValue::MSK_3: return String("MSK-3"); - case TimezoneValue::MST7: return String("MST7"); - case TimezoneValue::MST7MDTM320M1110: return String("MST7MDT,M3.2.0,M11.1.0"); - case TimezoneValue::NST330NDTM320M1110: return String("NST3:30NDT,M3.2.0,M11.1.0"); - case TimezoneValue::NZST_12NZDTM950M410_3: return String("NZST-12NZDT,M9.5.0,M4.1.0/3"); - case TimezoneValue::PKT_5: return String("PKT-5"); - case TimezoneValue::PST_8: return String("PST-8"); - case TimezoneValue::PST8PDTM320M1110: return String("PST8PDT,M3.2.0,M11.1.0"); - case TimezoneValue::SAST_2: return String("SAST-2"); - case TimezoneValue::SST11: return String("SST11"); - case TimezoneValue::UTC0: return String("UTC0"); - case TimezoneValue::WAT_1: return String("WAT-1"); - case TimezoneValue::WET0WESTM350_1M1050: return String("WET0WEST,M3.5.0/1,M10.5.0"); - case TimezoneValue::WIB_7: return String("WIB-7"); - case TimezoneValue::WIT_9: return String("WIT-9"); - case TimezoneValue::WITA_8: return String("WITA-8"); - default: return String("GMT0"); // Default fallback - } -} - -// Overload for std::string -inline std::string get_timezone_value_string_std(TimezoneValue value) { - return std::string(get_timezone_value_string(value).c_str()); -} - -} // namespace timezone_data diff --git a/lib/btclock/bitaxe_handler.cpp b/lib/btclock/bitaxe_handler.cpp deleted file mode 100644 index c51ca7c..0000000 --- a/lib/btclock/bitaxe_handler.cpp +++ /dev/null @@ -1,88 +0,0 @@ -#include "bitaxe_handler.hpp" - -std::array parseBitaxeHashRate(uint64_t hashrate) -{ - std::array ret; - ret.fill(""); // Initialize all elements to empty strings - - // Convert hashrate to GH/s and round to nearest integer - double hashRateGH = static_cast(hashrate) / std::pow(10, getHashrateMultiplier('G')); - std::string hashRateStr = std::to_string(static_cast(std::round(hashRateGH))); - - // Place the icons - ret[0] = "mdi:bitaxe"; - ret[NUM_SCREENS - 1] = "GH/S"; - - // Calculate the position where the digits should start - std::size_t textLength = hashRateStr.length(); - std::size_t startIndex = NUM_SCREENS - 1 - textLength; - - // Insert the "mdi:pickaxe" icon just before the digits - if (startIndex > 0) - { - ret[startIndex - 1] = "mdi:pickaxe"; - } - - // Place each digit - for (std::size_t i = 0; i < textLength; ++i) - { - ret[startIndex + i] = std::string(1, hashRateStr[i]); - } - - return ret; -} - -std::array parseBitaxeBestDiff(uint64_t difficulty) -{ - std::array ret; - ret.fill(""); - - // Add icons at the start - ret[0] = "mdi:bitaxe"; - ret[1] = "mdi:rocket"; - - if (difficulty == 0) { - ret[NUM_SCREENS - 1] = "0"; - return ret; - } - - // Find the appropriate suffix and format the number - const std::pair suffixes[] = { - {'Q', 15}, {'T', 12}, {'G', 9}, {'M', 6}, {'K', 3} - }; - - std::string text; - for (const auto& suffix : suffixes) { - if (difficulty >= std::pow(10, suffix.second)) { - double value = difficulty / std::pow(10, suffix.second); - char buffer[32]; - snprintf(buffer, sizeof(buffer), "%.1f", value); - text = buffer; - // Remove trailing zeros and decimal point if not needed - if (text.find('.') != std::string::npos) { - text = text.substr(0, text.find_last_not_of('0') + 1); - if (text.back() == '.') { - text.pop_back(); - } - } - text += suffix.first; - break; - } - } - - if (text.empty()) { - text = std::to_string(difficulty); - } - - // Calculate start position to right-align the text - std::size_t startIndex = NUM_SCREENS - text.length(); - - // Place the formatted difficulty string - for (std::size_t i = 0; i < text.length() && (startIndex + i) < NUM_SCREENS; ++i) - { - ret[startIndex + i] = std::string(1, text[i]); - } - - return ret; -} - diff --git a/lib/btclock/bitaxe_handler.hpp b/lib/btclock/bitaxe_handler.hpp deleted file mode 100644 index f1484ef..0000000 --- a/lib/btclock/bitaxe_handler.hpp +++ /dev/null @@ -1,7 +0,0 @@ -#include -#include -#include -#include "utils.hpp" - -std::array parseBitaxeHashRate(uint64_t hashrate); -std::array parseBitaxeBestDiff(uint64_t difficulty); diff --git a/lib/btclock/data_handler.cpp b/lib/btclock/data_handler.cpp index eaf4538..764417f 100644 --- a/lib/btclock/data_handler.cpp +++ b/lib/btclock/data_handler.cpp @@ -1,175 +1,57 @@ #include "data_handler.hpp" -#ifdef __EMSCRIPTEN__ -#include -#include -#endif -char getCurrencySymbol(char input) -{ - switch (input) - { - case CURRENCY_EUR: - return '['; - break; - case CURRENCY_GBP: - return ']'; - break; - case CURRENCY_JPY: - return '^'; - break; - case CURRENCY_AUD: - case CURRENCY_CAD: - case CURRENCY_USD: - return '$'; - break; - default: - return input; - } -} - -std::string getCurrencyCode(char input) -{ - switch (input) - { - case CURRENCY_EUR: - return CURRENCY_CODE_EUR; - break; - case CURRENCY_GBP: - return CURRENCY_CODE_GBP; - break; - case CURRENCY_JPY: - return CURRENCY_CODE_JPY; - break; - case CURRENCY_AUD: - return CURRENCY_CODE_AUD; - break; - case CURRENCY_CAD: - return CURRENCY_CODE_CAD; - break; - default: - return CURRENCY_CODE_USD; - } -} - -char getCurrencyChar(const std::string& input) -{ - if (input == "EUR") - return CURRENCY_EUR; - else if (input == "GBP") - return CURRENCY_GBP; - else if (input == "JPY") - return CURRENCY_JPY; - else if (input == "AUD") - return CURRENCY_AUD; - else if (input == "CAD") - return CURRENCY_CAD; - else - return CURRENCY_USD; // Assuming USD is the default for unknown inputs -} - -std::array parsePriceData(std::uint32_t price, char currencySymbol, bool useSuffixFormat, bool mowMode, bool shareDot) +std::array parsePriceData(std::uint32_t price, char currencySymbol, bool useSuffixFormat) { std::array ret; std::string priceString; - if (std::to_string(price).length() >= NUM_SCREENS || useSuffixFormat) - { - int numScreens = shareDot || mowMode ? NUM_SCREENS - 1 : NUM_SCREENS - 2; - priceString = getCurrencySymbol(currencySymbol) + formatNumberWithSuffix(price, numScreens, mowMode); - } - else - { - priceString = getCurrencySymbol(currencySymbol) + std::to_string(price); + if (std::to_string(price).length() >= NUM_SCREENS || useSuffixFormat) { + priceString = currencySymbol + formatNumberWithSuffix(price, NUM_SCREENS-2); + } else { + priceString = currencySymbol + std::to_string(price); } std::uint32_t firstIndex = 0; - if ((shareDot && priceString.length() <= (NUM_SCREENS)) || priceString.length() < (NUM_SCREENS)) + if (priceString.length() < (NUM_SCREENS)) { priceString.insert(priceString.begin(), NUM_SCREENS - priceString.length(), ' '); - - if (mowMode) + if (currencySymbol == '[') { - ret[0] = "MOW/UNITS"; + ret[0] = "BTC/EUR"; } else { - ret[0] = "BTC/" + getCurrencyCode(currencySymbol); + ret[0] = "BTC/USD"; } - - firstIndex = 1; } - - size_t dotPosition = priceString.find('.'); - if (shareDot && dotPosition != std::string::npos && dotPosition > 0) + for (std::uint32_t i = firstIndex; i < NUM_SCREENS; i++) { - std::vector tempArray; - if (dotPosition != std::string::npos && dotPosition > 0) - { - for (size_t i = 0; i < priceString.length(); ++i) - { - if (i == dotPosition - 1) - { - tempArray.push_back(std::string(1, priceString[i]) + "."); - ++i; // Skip the dot in the next iteration - } - else - { - tempArray.push_back(std::string(1, priceString[i])); - } - } - - // Copy from tempArray to ret - for (std::uint32_t i = firstIndex; i < NUM_SCREENS && i - firstIndex < tempArray.size(); ++i) - { - ret[i] = tempArray[i - firstIndex]; - } - } + ret[i] = priceString[i]; } - else - { - for (std::uint32_t i = firstIndex; i < NUM_SCREENS; i++) - { - ret[i] = std::string(1, priceString[i]); - } - } - return ret; } -std::array parseSatsPerCurrency(std::uint32_t price,char currencySymbol, bool withSatsSymbol) +std::array parseSatsPerCurrency(std::uint32_t price, char currencySymbol, bool withSatsSymbol) { std::array ret; std::string priceString = std::to_string(int(round(1 / float(price) * 10e7))); std::uint32_t firstIndex = 0; - std::uint8_t insertSatSymbol = NUM_SCREENS - priceString.length() - 1; + uint insertSatSymbol = NUM_SCREENS - priceString.length() - 1; if (priceString.length() < (NUM_SCREENS)) { - // Check if price is greater than 1 billion - if (price >= 100000000) + priceString.insert(priceString.begin(), NUM_SCREENS - priceString.length(), ' '); + + + if (currencySymbol == '[') { - double satsPerCurrency = (1.0 / static_cast(price)) * 1e8; // Calculate satoshis - std::ostringstream oss; - oss << std::fixed << std::setprecision(3) << satsPerCurrency; // Format with 3 decimal places - priceString = oss.str(); + ret[0] = "SATS/EUR"; } else { - priceString = std::to_string(static_cast(round(1.0 / static_cast(price) * 1e8))); // Default formatting - } - - // Pad the string with spaces if necessary - if (priceString.length() < NUM_SCREENS) - { - priceString.insert(priceString.begin(), NUM_SCREENS - priceString.length(), ' '); - } - - if (currencySymbol != CURRENCY_USD || price >= 100000000) // no time anymore when earlier than 1 - ret[0] = "SATS/" + getCurrencyCode(currencySymbol); - else ret[0] = "MSCW/TIME"; - + } firstIndex = 1; for (std::uint32_t i = firstIndex; i < NUM_SCREENS; i++) @@ -177,8 +59,7 @@ std::array parseSatsPerCurrency(std::uint32_t price,ch ret[i] = priceString[i]; } - if (withSatsSymbol) - { + if (withSatsSymbol) { ret[insertSatSymbol] = "STS"; } } @@ -206,8 +87,7 @@ std::array parseBlockHeight(std::uint32_t blockHeight) return ret; } -std::array parseBlockFees(std::uint16_t blockFees) -{ +std::array parseBlockFees(std::uint16_t blockFees) { std::array ret; std::string blockFeesString = std::to_string(blockFees); std::uint32_t firstIndex = 0; @@ -219,12 +99,12 @@ std::array parseBlockFees(std::uint16_t blockFees) firstIndex = 1; } - for (std::uint8_t i = firstIndex; i < NUM_SCREENS - 1; i++) + for (uint i = firstIndex; i < NUM_SCREENS-1; i++) { ret[i] = blockFeesString[i]; } - ret[NUM_SCREENS - 1] = "sat/vB"; + ret[NUM_SCREENS-1] = "sat/vB"; return ret; } @@ -235,8 +115,7 @@ std::array parseHalvingCountdown(std::uint32_t blockHe const std::uint32_t nextHalvingBlock = 210000 - (blockHeight % 210000); const std::uint32_t minutesToHalving = nextHalvingBlock * 10; - if (asBlocks) - { + if (asBlocks) { std::string blockNrString = std::to_string(nextHalvingBlock); std::uint32_t firstIndex = 0; @@ -251,9 +130,9 @@ std::array parseHalvingCountdown(std::uint32_t blockHe { ret[i] = blockNrString[i]; } - } - else - { + + } else { + const int years = floor(minutesToHalving / 525600); const int days = floor((minutesToHalving - (years * 525600)) / (24 * 60)); @@ -276,16 +155,22 @@ std::array parseMarketCap(std::uint32_t blockHeight, s std::array ret; std::uint32_t firstIndex = 0; double supply = getSupplyAtBlock(blockHeight); - uint64_t marketCap = static_cast(supply * double(price)); - - ret[0] = getCurrencyCode(currencySymbol) + "/MCAP"; + int64_t marketCap = static_cast(supply * double(price)); + if (currencySymbol == '[') + { + ret[0] = "EUR/MCAP"; + } + else + { + ret[0] = "USD/MCAP"; + } if (bigChars) { firstIndex = 1; // Serial.print("Market cap: "); // Serial.println(marketCap); - std::string priceString = currencySymbol + formatNumberWithSuffix(marketCap, (NUM_SCREENS - 2)); + std::string priceString = currencySymbol + formatNumberWithSuffix(marketCap, (NUM_SCREENS-2)); priceString.insert(priceString.begin(), NUM_SCREENS - priceString.length(), ' '); for (std::uint32_t i = firstIndex; i < NUM_SCREENS; i++) @@ -312,7 +197,7 @@ std::array parseMarketCap(std::uint32_t blockHeight, s ret[i] = ""; } - ret[NUM_SCREENS - groups - 1] = std::string(" ") + currencySymbol + " "; + ret[NUM_SCREENS - groups - 1] = " $ "; for (std::uint32_t i = 0; i < groups; i++) { ret[(NUM_SCREENS - groups + i)] = stringValue.substr(i * 3, 3).c_str(); @@ -320,71 +205,4 @@ std::array parseMarketCap(std::uint32_t blockHeight, s } return ret; -} - -#ifdef __EMSCRIPTEN__ -emscripten::val arrayToStringArray(const std::array &arr) -{ - emscripten::val jsArray = emscripten::val::array(); - for (const auto &str : arr) - { - jsArray.call("push", str); - } - return jsArray; -} - -emscripten::val vectorToStringArray(const std::vector &vec) -{ - emscripten::val jsArray = emscripten::val::array(); - for (size_t i = 0; i < vec.size(); ++i) - { - jsArray.set(i, vec[i]); - } - return jsArray; -} - -emscripten::val parseBlockHeightArray(std::uint32_t blockHeight) -{ - return arrayToStringArray(parseBlockHeight(blockHeight)); -} - -emscripten::val parsePriceDataArray(std::uint32_t price, const std::string ¤cySymbol, bool useSuffixFormat = false, bool mowMode = false, bool shareDot = false) -{ - return arrayToStringArray(parsePriceData(price, currencySymbol[0], useSuffixFormat, mowMode, shareDot)); -} - -emscripten::val parseHalvingCountdownArray(std::uint32_t blockHeight, bool asBlocks) -{ - return arrayToStringArray(parseHalvingCountdown(blockHeight, asBlocks)); -} - -emscripten::val parseMarketCapArray(std::uint32_t blockHeight, std::uint32_t price, const std::string ¤cySymbol, bool bigChars) -{ - return arrayToStringArray(parseMarketCap(blockHeight, price, currencySymbol[0], bigChars)); -} - -emscripten::val parseBlockFeesArray(std::uint16_t blockFees) -{ - return arrayToStringArray(parseBlockFees(blockFees)); -} - -emscripten::val parseSatsPerCurrencyArray(std::uint32_t price, const std::string ¤cySymbol, bool withSatsSymbol) -{ - return arrayToStringArray(parseSatsPerCurrency(price, currencySymbol[0], withSatsSymbol)); -} - -EMSCRIPTEN_BINDINGS(my_module) -{ - // emscripten::register_vector("StringList"); - - emscripten::function("parseBlockHeight", &parseBlockHeightArray); - emscripten::function("parseHalvingCountdown", &parseHalvingCountdownArray); - emscripten::function("parseMarketCap", &parseMarketCapArray); - emscripten::function("parseBlockFees", &parseBlockFeesArray); - emscripten::function("parseSatsPerCurrency", &parseSatsPerCurrencyArray); - emscripten::function("parsePriceData", &parsePriceDataArray); - - emscripten::function("arrayToStringArray", &arrayToStringArray); - emscripten::function("vectorToStringArray", &vectorToStringArray); -} -#endif \ No newline at end of file +} \ No newline at end of file diff --git a/lib/btclock/data_handler.hpp b/lib/btclock/data_handler.hpp index 4dda86b..b31cfe7 100644 --- a/lib/btclock/data_handler.hpp +++ b/lib/btclock/data_handler.hpp @@ -2,31 +2,12 @@ #include #include #include -#include #include "utils.hpp" -const char CURRENCY_USD = '$'; -const char CURRENCY_EUR = '['; -const char CURRENCY_GBP = ']'; -const char CURRENCY_JPY = '^'; -const char CURRENCY_AUD = '_'; -const char CURRENCY_CAD = '`'; - -const std::string CURRENCY_CODE_USD = "USD"; -const std::string CURRENCY_CODE_EUR = "EUR"; -const std::string CURRENCY_CODE_GBP = "GBP"; -const std::string CURRENCY_CODE_JPY = "JPY"; -const std::string CURRENCY_CODE_AUD = "AUD"; -const std::string CURRENCY_CODE_CAD = "CAD"; - -std::array parsePriceData(std::uint32_t price, char currency, bool useSuffixFormat = false, bool mowMode = false, bool shareDot = false); +std::array parsePriceData(std::uint32_t price, char currencySymbol, bool useSuffixFormat = false); std::array parseSatsPerCurrency(std::uint32_t price, char currencySymbol, bool withSatsSymbol); std::array parseBlockHeight(std::uint32_t blockHeight); std::array parseHalvingCountdown(std::uint32_t blockHeight, bool asBlocks); std::array parseMarketCap(std::uint32_t blockHeight, std::uint32_t price, char currencySymbol, bool bigChars); std::array parseBlockFees(std::uint16_t blockFees); - -char getCurrencySymbol(char input); -std::string getCurrencyCode(char input); -char getCurrencyChar(const std::string& input); \ No newline at end of file diff --git a/lib/btclock/nostrdisplay_handler.cpp b/lib/btclock/nostrdisplay_handler.cpp deleted file mode 100644 index 8fabe1f..0000000 --- a/lib/btclock/nostrdisplay_handler.cpp +++ /dev/null @@ -1,24 +0,0 @@ -#include "nostrdisplay_handler.hpp" - -std::array parseZapNotify(std::uint16_t amount, bool withSatsSymbol) -{ - std::string text = std::to_string(amount); - std::size_t textLength = text.length(); - std::size_t startIndex = NUM_SCREENS - textLength; - - std::array textEpdContent = {"ZAP", "mdi-lnbolt", "", "", "", "", ""}; - - // Insert the sats symbol just before the digits - if (startIndex > 0 && withSatsSymbol) - { - textEpdContent[startIndex - 1] = "STS"; - } - - // Place the digits - for (std::size_t i = 0; i < textLength; i++) - { - textEpdContent[startIndex + i] = text.substr(i, 1); - } - - return textEpdContent; -} \ No newline at end of file diff --git a/lib/btclock/nostrdisplay_handler.hpp b/lib/btclock/nostrdisplay_handler.hpp deleted file mode 100644 index dd2b8ed..0000000 --- a/lib/btclock/nostrdisplay_handler.hpp +++ /dev/null @@ -1,5 +0,0 @@ -#include -#include -#include "utils.hpp" - -std::array parseZapNotify(std::uint16_t amount, bool withSatsSymbol); diff --git a/lib/btclock/utils.cpp b/lib/btclock/utils.cpp index 443eb1e..b801fc2 100644 --- a/lib/btclock/utils.cpp +++ b/lib/btclock/utils.cpp @@ -28,12 +28,7 @@ double getSupplyAtBlock(std::uint32_t blockNr) return totalBitcoinInCirculation; } -std::string formatNumberWithSuffix(std::uint64_t num, int numCharacters) -{ - return formatNumberWithSuffix(num, numCharacters, false); -} - -std::string formatNumberWithSuffix(std::uint64_t num, int numCharacters, bool mowMode) +std::string formatNumberWithSuffix(std::uint64_t num, int numCharacters) { static char result[20]; // Adjust size as needed const long long quadrillion = 1000000000000000LL; @@ -61,196 +56,30 @@ std::string formatNumberWithSuffix(std::uint64_t num, int numCharacters, bool mo numDouble /= billion; suffix = 'B'; } - else if (num >= million || numDigits > 6 || (mowMode && num >= thousand)) + else if (num >= million || numDigits > 6) { numDouble /= million; suffix = 'M'; } - else if (!mowMode && (num >= thousand || numDigits > 3)) + else if (num >= thousand || numDigits > 3) { numDouble /= thousand; suffix = 'K'; } - else if (!mowMode) + else { - snprintf(result, sizeof(result), "%llu", (unsigned long long)num); + sprintf(result, "%llu", (unsigned long long)num); return result; } - else // mowMode is true and num < 1000 - { - numDouble /= million; - suffix = 'M'; - } // Add suffix - int len; + int len = snprintf(result, sizeof(result), "%.0f%c", numDouble, suffix); - // Mow Mode always uses string truncation to avoid rounding - std::string mowAsString = std::to_string(numDouble); - if (mowMode) { - // Default to one decimal place - len = snprintf(result, sizeof(result), "%s%c", mowAsString.substr(0, mowAsString.find(".") + 2).c_str(), suffix); - } - else - { - len = snprintf(result, sizeof(result), "%.0f%c", numDouble, suffix); - } - - // If there's room, add more decimal places + // If there's room, add decimal places if (len < numCharacters) { - int restLen = mowMode ? numCharacters - len : numCharacters - len - 1; - - if (mowMode) { - snprintf(result, sizeof(result), "%s%c", mowAsString.substr(0, mowAsString.find(".") + 2 + restLen).c_str(), suffix); - } - else - { - snprintf(result, sizeof(result), "%.*f%c", restLen, numDouble, suffix); - } + snprintf(result, sizeof(result), "%.*f%c", numCharacters - len - 1, numDouble, suffix); } return result; -} - -/** - * Get sat amount from a bolt11 invoice - * - * Based on https://github.com/lnbits/nostr-zap-lamp/blob/main/nostrZapLamp/nostrZapLamp.ino - */ -int64_t getAmountInSatoshis(std::string bolt11) { - int64_t number = -1; - char multiplier = ' '; - - for (unsigned int i = 0; i < bolt11.length(); ++i) { - if (isdigit(bolt11[i])) { - number = 0; - while (isdigit(bolt11[i])) { - number = number * 10 + (bolt11[i] - '0'); - ++i; - } - for (unsigned int j = i; j < bolt11.length(); ++j) { - if (isalpha(bolt11[j])) { - multiplier = bolt11[j]; - break; - } - } - break; - } - } - - if (number == -1 || multiplier == ' ') { - return -1; - } - - int64_t satoshis = number; - - switch (multiplier) { - case 'm': - satoshis *= 100000; // 0.001 * 100,000,000 - break; - case 'u': - satoshis *= 100; // 0.000001 * 100,000,000 - break; - case 'n': - satoshis /= 10; // 0.000000001 * 100,000,000 - break; - case 'p': - satoshis /= 10000; // 0.000000000001 * 100,000,000 - break; - default: - return -1; - } - - return satoshis; -} - -void parseHashrateString(const std::string& hashrate, std::string& label, std::string& output, unsigned int maxCharacters) { - // Handle empty string or "0" cases - if (hashrate.empty() || hashrate == "0") { - label = "H/S"; - output = "0"; - return; - } - - size_t suffixLength = 0; - if (hashrate.length() > 21) { - label = "ZH/S"; - suffixLength = 21; - } else if (hashrate.length() > 18) { - label = "EH/S"; - suffixLength = 18; - } else if (hashrate.length() > 15) { - label = "PH/S"; - suffixLength = 15; - } else if (hashrate.length() > 12) { - label = "TH/S"; - suffixLength = 12; - } else if (hashrate.length() > 9) { - label = "GH/S"; - suffixLength = 9; - } else if (hashrate.length() > 6) { - label = "MH/S"; - suffixLength = 6; - } else if (hashrate.length() > 3) { - label = "KH/S"; - suffixLength = 3; - } else { - label = "H/S"; - suffixLength = 0; - } - - double value = std::stod(hashrate) / std::pow(10, suffixLength); - - // Calculate integer part length - int integerPartLength = std::to_string(static_cast(value)).length(); - - // Calculate remaining space for decimals - int remainingSpace = maxCharacters - integerPartLength; - - char buffer[32]; - if (remainingSpace <= 0) - { - // No space for decimals, just round to integer - snprintf(buffer, sizeof(buffer), "%.0f", value); - } - else - { - // Space for decimal point and some decimals - snprintf(buffer, sizeof(buffer), "%.*f", remainingSpace - 1, value); - } - - // Remove trailing zeros and decimal point if necessary - output = buffer; - if (output.find('.') != std::string::npos) - { - output = output.substr(0, output.find_last_not_of('0') + 1); - if (output.back() == '.') - { - output.pop_back(); - } - } - -} - -int getHashrateMultiplier(char unit) { - if (unit == '0') - return 0; - - static const std::unordered_map multipliers = { - {'Z', 21}, {'E', 18}, {'P', 15}, {'T', 12}, - {'G', 9}, {'M', 6}, {'K', 3} - }; - return multipliers.at(unit); -} - -int getDifficultyMultiplier(char unit) { - if (unit == '0') - return 0; - - static const std::unordered_map multipliers = { - {'Q', 15}, {'T', 12}, {'B', 9}, {'M', 6}, {'K', 3}, {'G', 9}, - {'q', 15}, {'t', 12}, {'b', 9}, {'m', 6}, {'k', 3}, {'g', 9} - }; - return multipliers.at(unit); -} +} \ No newline at end of file diff --git a/lib/btclock/utils.hpp b/lib/btclock/utils.hpp index 05540d4..db338c0 100644 --- a/lib/btclock/utils.hpp +++ b/lib/btclock/utils.hpp @@ -5,16 +5,9 @@ #include #include #include -#include - int modulo(int x,int N); double getSupplyAtBlock(std::uint32_t blockNr); -std::string formatNumberWithSuffix(std::uint64_t num, int numCharacters = 4); -std::string formatNumberWithSuffix(std::uint64_t num, int numCharacters, bool mowMode); -int64_t getAmountInSatoshis(std::string bolt11); -void parseHashrateString(const std::string& hashrate, std::string& label, std::string& output, unsigned int maxCharacters); -int getHashrateMultiplier(char unit); -int getDifficultyMultiplier(char unit); \ No newline at end of file +std::string formatNumberWithSuffix(std::uint64_t num, int numCharacters = 4); \ No newline at end of file diff --git a/maintainers.yaml b/maintainers.yaml deleted file mode 100644 index 8176c63..0000000 --- a/maintainers.yaml +++ /dev/null @@ -1,20 +0,0 @@ -identifier: BTClock -maintainers: -- npub1k5f85zx0xdskyayqpfpc0zq6n7vwqjuuxugkayk72fgynp34cs3qfcvqg2 -relays: -- wss://relay.noderunners.network/ -- wss://nostr.sathoarder.com/ -- wss://offchain.pub/ -- wss://nostr3.daedaluslabs.io/ -- wss://nostr4.daedaluslabs.io/ -- wss://nostr.dbtc.link/ -- wss://purplepag.es/ -- wss://nos.lol/ -- wss://nostr1.daedaluslabs.io/ -- wss://nostr.noderunners.network/ -- wss://nostr.lnbitcoin.cz/ -- wss://relay.primal.net/ -- wss://relay.damus.io -- wss://nostr-relay.derekross.me/ -- wss://nostr2.azzamo.net/ -- wss://nostr2.daedaluslabs.io/ diff --git a/partition.csv b/partition.csv index eedbf5b..4ca1357 100644 --- a/partition.csv +++ b/partition.csv @@ -1,7 +1,7 @@ # Name, Type, SubType, Offset, Size, Flags -nvs, data, nvs, 0x9000, 0x5000, -otadata, data, ota, 0xe000, 0x2000, -app0, app, ota_0, 0x10000, 0x1b8000, -app1, app, ota_1, , 0x1b8000, -spiffs, data, spiffs, , 0x66C00, -coredump, data, coredump,, 0x10000, +nvs, data, nvs, 36K, 20K, +otadata, data, ota, 56K, 8K, +app0, app, ota_0, 64K, 1700K, +app1, app, ota_1, , 1700K, +spiffs, data, spiffs, , 400K, +coredump, data, coredump,, 64K, diff --git a/partition_16mb.csv b/partition_16mb.csv index 7e58611..80df02b 100644 --- a/partition_16mb.csv +++ b/partition_16mb.csv @@ -1,7 +1,7 @@ # Name, Type, SubType, Offset, Size, Flags -nvs, data, nvs, 0x9000, 0x5000, -otadata, data, ota, 0xe000, 0x2000, -app0, app, ota_0, 0x10000, 0x6F0000, -app1, app, ota_1, , 0x6F0000, -spiffs, data, spiffs, , 0x200000, -coredump, data, coredump,, 0x10000, \ No newline at end of file +nvs, data, nvs, 36K, 20K, +otadata, data, ota, 56K, 8K, +app0, app, ota_0, 64K, 4096K, +app1, app, ota_1, , 4096K, +spiffs, data, spiffs, , 3072K, +coredump, data, coredump,, 64K, diff --git a/partition_8mb.csv b/partition_8mb.csv deleted file mode 100644 index 025f649..0000000 --- a/partition_8mb.csv +++ /dev/null @@ -1,7 +0,0 @@ -# Name, Type, SubType, Offset, Size, Flags -nvs, data, nvs, 0x9000, 0x5000, -otadata, data, ota, 0xe000, 0x2000, -app0, app, ota_0, 0x10000, 0x370000, -app1, app, ota_1, , 0x370000, -spiffs, data, spiffs, , 0xCD000, -coredump, data, coredump,, 0x10000, \ No newline at end of file diff --git a/platformio.ini b/platformio.ini index be356f0..dffad22 100644 --- a/platformio.ini +++ b/platformio.ini @@ -7,194 +7,103 @@ ; ; Please visit documentation for the other options and examples ; https://docs.platformio.org/page/projectconf.html - [platformio] data_dir = data/build_gz -default_envs = lolin_s3_mini_213epd, lolin_s3_mini_29epd, btclock_rev_b_213epd, btclock_v8_213epd +default_envs = lolin_s3_mini_213epd, lolin_s3_mini_29epd [env] + [btclock_base] -platform = espressif32 @ ^6.10.0 -framework = arduino, espidf +platform = espressif32 @ ^6.5.0 +framework = arduino, espidf monitor_speed = 115200 monitor_filters = esp32_exception_decoder, colorize board_build.filesystem = littlefs -extra_scripts = pre:scripts/pre_script.py, post:scripts/extra_script.py -platform_packages = - earlephilhower/tool-mklittlefs-rp2040-earlephilhower -board_build.embed_files = - x509_crt_bundle -build_flags = - !python scripts/git_rev.py - -DLAST_BUILD_TIME=$UNIX_TIME - -DARDUINO_USB_CDC_ON_BOOT - -DCORE_DEBUG_LEVEL=0 - -D CONFIG_ASYNC_TCP_STACK_SIZE=16384 - -fexceptions +extra_scripts = post:scripts/extra_script.py +build_flags = + !python scripts/git_rev.py + -DLAST_BUILD_TIME=$UNIX_TIME + -DARDUINO_USB_CDC_ON_BOOT + -DCORE_DEBUG_LEVEL=0 + -fexceptions build_unflags = - -Werror=all - -fno-exceptions + -Werror=all + -fno-exceptions lib_deps = - https://github.com/joltwallet/esp_littlefs.git#v1.16.4 - bblanchon/ArduinoJson@^7.4.1 - esp32async/ESPAsyncWebServer @ 3.7.7 - robtillaart/MCP23017@^0.9.1 - adafruit/Adafruit NeoPixel@^1.15.1 - https://github.com/dsbaars/universal_pin#feature/mcp23017_rt - https://github.com/dsbaars/GxEPD2#universal_pin - https://github.com/tzapu/WiFiManager.git#v2.0.17 - https://github.com/dsbaars/nostrduino#feature/fix-btclock + https://github.com/joltwallet/esp_littlefs.git + bblanchon/ArduinoJson@^7.0.3 + esphome/Improv@^1.2.3 + mathieucarbou/ESP Async WebServer + adafruit/Adafruit BusIO@^1.15.0 + adafruit/Adafruit MCP23017 Arduino Library@^2.3.2 + adafruit/Adafruit NeoPixel@^1.12.0 + https://github.com/dsbaars/universal_pin + https://github.com/dsbaars/GxEPD2#universal_pin + https://github.com/tzapu/WiFiManager.git#v2.0.16-rc.2 [env:lolin_s3_mini] extends = btclock_base board = lolin_s3_mini board_build.partitions = partition.csv -build_flags = - ${btclock_base.build_flags} - -D MCP_INT_PIN=8 - -D NEOPIXEL_PIN=34 - -D NEOPIXEL_COUNT=4 - -D NUM_SCREENS=7 - -D I2C_SDA_PIN=35 - -D I2C_SCK_PIN=36 - -DARDUINO_USB_CDC_ON_BOOT=1 - -D IS_HW_REV_A +build_flags = + ${btclock_base.build_flags} + -D MCP_INT_PIN=8 + -D NEOPIXEL_PIN=34 + -D NEOPIXEL_COUNT=4 + -D NUM_SCREENS=7 + -D I2C_SDA_PIN=35 + -D I2C_SCK_PIN=36 build_unflags = - ${btclock_base.build_unflags} -platform_packages = - platformio/tool-mklittlefs@^1.203.210628 - earlephilhower/tool-mklittlefs-rp2040-earlephilhower@^5.100300.230216 - -[env:btclock_rev_b] -extends = btclock_base -board = btclock_rev_b -board_build.partitions = partition_8mb.csv -build_flags = - ${btclock_base.build_flags} - -D MCP_INT_PIN=8 - -D NEOPIXEL_PIN=15 - -D NEOPIXEL_COUNT=4 - -D NUM_SCREENS=7 - -D I2C_SDA_PIN=35 - -D I2C_SCK_PIN=36 - -D HAS_FRONTLIGHT - -D PCA_OE_PIN=48 - -D PCA_I2C_ADDR=0x42 - -D IS_HW_REV_B - -lib_deps = - ${btclock_base.lib_deps} - robtillaart/PCA9685@^0.7.1 - claws/BH1750@^1.3.0 -build_unflags = - ${btclock_base.build_unflags} -platform_packages = - platformio/tool-mklittlefs@^1.203.210628 - earlephilhower/tool-mklittlefs-rp2040-earlephilhower@^5.100300.230216 + ${btclock_base.build_unflags} [env:lolin_s3_mini_213epd] extends = env:lolin_s3_mini test_framework = unity -build_flags = - ${env:lolin_s3_mini.build_flags} - -D USE_QR - -D VERSION_EPD_2_13 - -D HW_REV=\"REV_A_EPD_2_13\" - -D CONFIG_ARDUINO_MAIN_TASK_STACK_SIZE=16384 -platform_packages = - platformio/tool-mklittlefs@^1.203.210628 - earlephilhower/tool-mklittlefs-rp2040-earlephilhower@^5.100300.230216 - -[env:btclock_rev_b_213epd] -extends = env:btclock_rev_b -test_framework = unity -build_flags = - ${env:btclock_rev_b.build_flags} - -D USE_QR - -D VERSION_EPD_2_13 - -D HW_REV=\"REV_B_EPD_2_13\" - -D CONFIG_ARDUINO_MAIN_TASK_STACK_SIZE=16384 -platform_packages = - platformio/tool-mklittlefs@^1.203.210628 - earlephilhower/tool-mklittlefs-rp2040-earlephilhower@^5.100300.230216 +build_flags = + ${env:lolin_s3_mini.build_flags} + -D USE_QR + -D VERSION_EPD_2_13 [env:lolin_s3_mini_29epd] extends = env:lolin_s3_mini test_framework = unity -build_flags = - ${env:lolin_s3_mini.build_flags} - -D USE_QR - -D VERSION_EPD_2_9 - -D HW_REV=\"REV_A_EPD_2_9\" -platform_packages = - platformio/tool-mklittlefs@^1.203.210628 - earlephilhower/tool-mklittlefs-rp2040-earlephilhower@^5.100300.230216 +build_flags = + ${env:lolin_s3_mini.build_flags} + -D USE_QR + -D VERSION_EPD_2_9 -[env:btclock_rev_b_29epd] -extends = env:btclock_rev_b -test_framework = unity -build_flags = - ${env:btclock_rev_b.build_flags} - -D USE_QR - -D VERSION_EPD_2_9 - -D HW_REV=\"REV_B_EPD_2_9\" -platform_packages = - platformio/tool-mklittlefs@^1.203.210628 - earlephilhower/tool-mklittlefs-rp2040-earlephilhower@^5.100300.230216 - -[env:btclock_v8] +[env:btclock_s3] extends = btclock_base -board = btclock_v8 +board = btclock board_build.partitions = partition_16mb.csv -board_build.flash_mode = qio test_framework = unity -build_flags = - ${btclock_base.build_flags} - -D MCP_INT_PIN=4 - -D NEOPIXEL_PIN=5 - -D NEOPIXEL_COUNT=4 - -D NUM_SCREENS=8 - -D SPI_SDA_PIN=11 - -D SPI_SCK_PIN=12 - -D I2C_SDA_PIN=1 - -D I2C_SCK_PIN=2 - -D MCP_RESET_PIN=21 - -D MCP1_A0_PIN=6 - -D MCP1_A1_PIN=7 - -D MCP1_A2_PIN=8 - -D MCP2_A0_PIN=9 - -D MCP2_A1_PIN=10 - -D MCP2_A2_PIN=14 +build_flags = + ${btclock_base.build_flags} + -D MCP_INT_PIN=4 + -D NEOPIXEL_PIN=5 + -D NEOPIXEL_COUNT=4 + -D NUM_SCREENS=8 + -D SPI_SDA_PIN=11 + -D SPI_SCK_PIN=12 + -D I2C_SDA_PIN=1 + -D I2C_SCK_PIN=2 + -D MCP_RESET_PIN=21 + -D MCP1_A0_PIN=6 + -D MCP1_A1_PIN=7 + -D MCP1_A2_PIN=8 + -D MCP2_A0_PIN=9 + -D MCP2_A1_PIN=10 + -D MCP2_A2_PIN=14 build_unflags = - ${btclock_base.build_unflags} -platform_packages = - platformio/tool-mklittlefs@^1.203.210628 - earlephilhower/tool-mklittlefs-rp2040-earlephilhower@^5.100300.230216 - -[env:btclock_v8_213epd] -extends = env:btclock_v8 -test_framework = unity -build_flags = - ${env:btclock_v8.build_flags} - -D USE_QR - -D VERSION_EPD_2_13 - -D HW_REV=\"REV_V8_EPD_2_13\" -platform_packages = - platformio/tool-mklittlefs@^1.203.210628 - earlephilhower/tool-mklittlefs-rp2040-earlephilhower@^5.100300.230216 + ${btclock_base.build_unflags} [env:native_test_only] platform = native test_framework = unity -build_flags = - ${btclock_base.build_flags} - -D MCP_INT_PIN=8 - -D NEOPIXEL_PIN=34 - -D NEOPIXEL_COUNT=4 - -D NUM_SCREENS=7 - -D UNITY_TEST - -std=gnu++17 -platform_packages = - platformio/tool-mklittlefs@^1.203.210628 - earlephilhower/tool-mklittlefs-rp2040-earlephilhower@^5.100300.230216 +build_flags = + ${btclock_base.build_flags} + -D MCP_INT_PIN=8 + -D NEOPIXEL_PIN=34 + -D NEOPIXEL_COUNT=4 + -D NUM_SCREENS=7 \ No newline at end of file diff --git a/renovate.json b/renovate.json deleted file mode 100644 index 5db72dd..0000000 --- a/renovate.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "$schema": "https://docs.renovatebot.com/renovate-schema.json", - "extends": [ - "config:recommended" - ] -} diff --git a/requirements.txt b/requirements.txt deleted file mode 100644 index a91b030..0000000 --- a/requirements.txt +++ /dev/null @@ -1 +0,0 @@ -platformio \ No newline at end of file diff --git a/scripts/extra_script.py b/scripts/extra_script.py index ebc94e9..4a1c118 100644 --- a/scripts/extra_script.py +++ b/scripts/extra_script.py @@ -1,18 +1,8 @@ Import("env") import os import gzip -from shutil import copyfileobj, rmtree, copyfile, copytree +from shutil import copyfileobj, rmtree from pathlib import Path -import subprocess - - - - -revision = ( - subprocess.check_output(["git", "rev-parse", "HEAD"]) - .strip() - .decode("utf-8") -) def gzip_file(input_file, output_file): with open(input_file, 'rb') as f_in: @@ -29,97 +19,20 @@ def process_directory(input_dir, output_dir): Path(output_root).mkdir(parents=True, exist_ok=True) for file in files: -# if not file.endswith(('.bin')): + # if file.endswith(('.html', '.css', '.js')): input_file_path = os.path.join(root, file) output_file_path = os.path.join(output_root, file + '.gz') gzip_file(input_file_path, output_file_path) print(f'Compressed: {input_file_path} -> {output_file_path}') - file_path = os.path.join(output_dir, "fs_hash.txt") - with open(file_path, "w") as file: - file.write(revision) + # Build web interface before building FS def before_buildfs(source, target, env): - env.Execute("cd data && yarn && yarn postinstall && yarn build") input_directory = 'data/dist' output_directory = 'data/build_gz' -# copytree("assets", "data/dist/assets") - process_directory(input_directory, output_directory) -def get_fs_partition_size(env): - import csv - - # Get partition table path - first try custom, then default - board_config = env.BoardConfig() - partition_table = board_config.get("build.partitions", "default.csv") - - # Handle default partition table path - if partition_table == "default.csv" or partition_table == "huge_app.csv": - partition_table = os.path.join(env.PioPlatform().get_package_dir("framework-arduinoespressif32"), - "tools", "partitions", partition_table) - - # Parse CSV to find spiffs/littlefs partition - with open(partition_table, 'r') as f: - for row in csv.reader(f): - if len(row) < 5: - continue - # Remove comments and whitespace - row = [cell.strip().split('#')[0] for cell in row] - # Check if this is a spiffs or littlefs partition - if row[0].startswith(('spiffs', 'littlefs')): - # Size is in hex format - return int(row[4], 16) - return 0 - -def get_littlefs_used_size(binary_path): - mklittlefs_path = os.path.join(env.PioPlatform().get_package_dir("tool-mklittlefs-rp2040-earlephilhower"), "mklittlefs") - - try: - result = subprocess.run([mklittlefs_path, '-l', binary_path], capture_output=True, text=True) - - if result.returncode == 0: - # Parse the output to sum up file sizes - total_size = 0 - for line in result.stdout.splitlines(): - if line.strip() and not line.startswith('') and not line.startswith('Creation'): - # Each line format: size filename - size = line.split()[0] - total_size += int(size) - return total_size - except Exception as e: - print(f"Error getting filesystem size: {e}") - return 0 - - -def after_littlefs(source, target, env): - binary_path = str(target[0]) - partition_size = get_fs_partition_size(env) - used_size = get_littlefs_used_size(binary_path) - - percentage = (used_size / partition_size) * 100 - bar_width = 50 - filled = int(bar_width * percentage / 100) - bar = '=' * filled + '-' * (bar_width - filled) - - print(f"\nLittleFS Actual Usage: [{bar}] {percentage:.1f}% ({used_size}/{partition_size} bytes)") - - -flash_size = env.BoardConfig().get("upload.flash_size", "4MB") -fs_image_name = f"littlefs_{flash_size}" -env.Replace(ESP32_FS_IMAGE_NAME=fs_image_name) -env.Replace(ESP8266_FS_IMAGE_NAME=fs_image_name) - os.environ["PUBLIC_BASE_URL"] = "" -fs_name = env.get("ESP32_FS_IMAGE_NAME", "littlefs.bin") -# Or alternatively: -# fs_name = env.get("FSTOOLNAME", "littlefs.bin") - -# Use the variable in the pre-action -env.AddPreAction(f"$BUILD_DIR/{fs_name}.bin", before_buildfs) -env.AddPostAction(f"$BUILD_DIR/{fs_name}.bin", after_littlefs) -# LittleFS Actual Usage: [==============================--------------------] 60.4% (254165/420864 bytes) -# LittleFS Actual Usage: [==============================--------------------] 60.2% (253476/420864 bytes) -# 372736 used \ No newline at end of file +env.AddPreAction("$BUILD_DIR/littlefs.bin", before_buildfs) diff --git a/scripts/find_btclocks.py b/scripts/find_btclocks.py index ab1977a..79aa3de 100644 --- a/scripts/find_btclocks.py +++ b/scripts/find_btclocks.py @@ -48,8 +48,8 @@ class Listener(ServiceListener): #arguments = [f"-i {str()} -f -r"] namespace = argparse.Namespace( esp_ip=info.parsed_addresses()[0], - image=f"{os.getcwd()}/.pio/build/lolin_s3_mini_213epd/firmware.bin", - littlefs=f"{os.getcwd()}/.pio/build/lolin_s3_mini_213epd/littlefs.bin", + image=f"{os.getcwd()}/.pio/build/lolin_s3_mini_qr/firmware.bin", + littlefs=f"{os.getcwd()}/.pio/build/lolin_s3_mini_qr/littlefs.bin", progress=True ) if (str(info.properties.get(b"version").decode())) != "3.0": @@ -64,7 +64,7 @@ class Listener(ServiceListener): print("Different version, going to update") #espota.serve(namespace.esp_ip, "0.0.0.0", 3232, random.randint(10000,60000), "", namespace.littlefs, SPIFFS) - espota.serve(namespace.esp_ip, "0.0.0.0", 3232, random.randint(10000,60000), "", namespace.image, FLASH) + #espota.serve(namespace.esp_ip, "0.0.0.0", 3232, random.randint(10000,60000), "", namespace.image, FLASH) #print(arguments) #logging.basicConfig(level = logging.DEBUG, format = '%(asctime)-8s [%(levelname)s]: %(message)s', datefmt = '%H:%M:%S') diff --git a/scripts/git_rev.py b/scripts/git_rev.py index 5ac166a..9594475 100644 --- a/scripts/git_rev.py +++ b/scripts/git_rev.py @@ -5,17 +5,4 @@ revision = ( .strip() .decode("utf-8") ) - -try: - tag = ( - subprocess.check_output(["git", "describe", "--tags", "--exact-match"]) - .strip() - .decode("utf-8") - ) - git_tag_define = '\'-DGIT_TAG=\"%s\"\'' % tag -except subprocess.CalledProcessError: - git_tag_define = '' - -print("'-DGIT_REV=\"%s\"'" % revision) -if git_tag_define: - print(git_tag_define) \ No newline at end of file +print("'-DGIT_REV=\"%s\"'" % revision) \ No newline at end of file diff --git a/scripts/pre_script.py b/scripts/pre_script.py deleted file mode 100644 index 45d6bea..0000000 --- a/scripts/pre_script.py +++ /dev/null @@ -1,7 +0,0 @@ -Import("env") - -flash_size = env.BoardConfig().get("upload.flash_size", "4MB") -fs_image_name = f"littlefs_{flash_size}" -env.Replace(ESP32_FS_IMAGE_NAME=fs_image_name) -env.Replace(ESP8266_FS_IMAGE_NAME=fs_image_name) - diff --git a/sdkconfig.defaults b/sdkconfig.defaults index 3294889..09888de 100644 --- a/sdkconfig.defaults +++ b/sdkconfig.defaults @@ -7,8 +7,8 @@ CONFIG_MBEDTLS_KEY_EXCHANGE_PSK=y #CONFIG_FREERTOS_USE_TRACE_FACILITY=y #CONFIG_FREERTOS_USE_STATS_FORMATTING_FUNCTIONS=y #CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS=n -#CONFIG_ESP_TLS_INSECURE=y -#CONFIG_ESP_TLS_SKIP_SERVER_CERT_VERIFY=y +CONFIG_ESP_TLS_INSECURE=y +CONFIG_ESP_TLS_SKIP_SERVER_CERT_VERIFY=y CONFIG_HEAP_CORRUPTION_DETECTION=CONFIG_HEAP_POISONING_LIGHT CONFIG_HEAP_POISONING_LIGHT=y @@ -16,14 +16,18 @@ CONFIG_HEAP_POISONING_LIGHT=y CONFIG_ESP32S3_SPIRAM_SUPPORT=y CONFIG_SPIRAM_TRY_ALLOCATE_WIFI_LWIP=y CONFIG_BOOTLOADER_LOG_LEVEL=0 +CONFIG_LOG_BOOTLOADER_LEVEL_NONE=y CONFIG_BOOTLOADER_LOG_LEVEL_NONE=y CONFIG_ESP32S3_SPIRAM_SUPPORT=y CONFIG_LOG_DEFAULT_LEVEL_NONE=y CONFIG_LOG_DEFAULT_LEVEL=0 CONFIG_LOG_MAXIMUM_LEVEL=0 +CONFIG_LOG_BOOTLOADER_LEVEL_NONE=y +CONFIG_LOG_BOOTLOADER_LEVEL=0 +CONFIG_CXX_EXCEPTIONS=y CONFIG_COMPILER_CXX_EXCEPTIONS=y #CONFIG_BOOTLOADER_WDT_ENABLE=n -#CONFIG_ESP_TASK_WDT=n +#CONFIG_TASK_WDT=n #Required for BTClock #CONFIG_SPIRAM_MODE_OCT=y @@ -38,11 +42,12 @@ CONFIG_ESP_WIFI_DYNAMIC_TX_BUFFER_NUM=12 CONFIG_ESP32_WIFI_RX_BA_WIN=6 CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH=3120 +CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ_240 CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ_240=y CONFIG_RTC_CLK_CAL_CYCLES=576 CONFIG_FREERTOS_WATCHPOINT_END_OF_STACK=y CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH=3120 CONFIG_ESP_SYSTEM_MEMPROT_FEATURE=n CONFIG_SPIRAM_CACHE_WORKAROUND=y -CONFIG_COMPILER_OPTIMIZATION_SIZE=y -#CONFIG_NEWLIB_NANO_FORMAT=y \ No newline at end of file +CONFIG_COMPILER_OPTIMIZATION_PERF=y +CONFIG_COMPILER_OPTIMIZATION_LEVEL_RELEASE=y \ No newline at end of file diff --git a/src/fonts/antonio-semibold20.h b/src/fonts/antonio-semibold20.h index be8b1ec..d544b08 100644 --- a/src/fonts/antonio-semibold20.h +++ b/src/fonts/antonio-semibold20.h @@ -1,191 +1,384 @@ -#pragma once - #include #include -#include "fonts.hpp" -const uint8_t Antonio_SemiBold20pt7bBitmaps_Gzip[] = { - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xa5, 0x57, - 0x4f, 0x6f, 0xe3, 0xba, 0x11, 0xa7, 0xaa, 0xe2, 0xf1, 0x1d, 0x16, 0xe6, - 0xf5, 0x1d, 0xbc, 0x62, 0x3f, 0xc2, 0xeb, 0xcd, 0x8b, 0x55, 0xac, 0xaf, - 0xf2, 0x4e, 0x7b, 0x76, 0xb0, 0x40, 0x57, 0x46, 0x94, 0x48, 0x81, 0x81, - 0xea, 0x52, 0xac, 0xaf, 0x5b, 0x60, 0x9b, 0x7c, 0x8d, 0x2d, 0x10, 0x6c, - 0x64, 0x08, 0x78, 0xbe, 0x45, 0x5f, 0x60, 0x11, 0x53, 0x10, 0x50, 0x5f, - 0x8a, 0x8a, 0x86, 0x80, 0x4a, 0x41, 0x14, 0xb1, 0x3f, 0xd2, 0x72, 0xfe, - 0x6c, 0xb2, 0xd9, 0xd7, 0x96, 0xa4, 0x39, 0x43, 0x8a, 0x96, 0x86, 0x33, - 0xc3, 0xdf, 0x0c, 0x89, 0xea, 0xcb, 0x1b, 0x5d, 0x08, 0xd3, 0x6c, 0x79, - 0x70, 0x59, 0x7f, 0xf8, 0x95, 0xd8, 0x73, 0x6b, 0x19, 0x15, 0xd1, 0x26, - 0x99, 0x88, 0xd1, 0x64, 0xe8, 0x0f, 0x5c, 0x3a, 0xa4, 0xef, 0xed, 0x98, - 0x9b, 0xe5, 0xed, 0x48, 0xb8, 0x13, 0x67, 0x34, 0x18, 0xd2, 0x81, 0x3d, - 0x67, 0xaa, 0x56, 0xcd, 0xdd, 0x3a, 0x66, 0xd6, 0x59, 0x69, 0x54, 0x24, - 0xfb, 0xc2, 0x17, 0xe4, 0x07, 0xf2, 0xb3, 0x15, 0xbd, 0x20, 0xbf, 0xf0, - 0x85, 0x3a, 0x6d, 0xaf, 0xeb, 0xf8, 0x6c, 0x2f, 0x2f, 0x99, 0x7f, 0x50, - 0xac, 0x48, 0x60, 0x35, 0x4c, 0x78, 0x51, 0x60, 0x49, 0x9a, 0x8c, 0x65, - 0x1d, 0xb7, 0x5e, 0xae, 0x58, 0x7b, 0xa0, 0xb2, 0xce, 0x13, 0x9d, 0x95, - 0x0c, 0xc8, 0xc4, 0x8e, 0x86, 0x84, 0x47, 0x56, 0x42, 0x3b, 0xe2, 0x92, - 0x50, 0xd8, 0x09, 0x3b, 0x25, 0x23, 0x22, 0x25, 0x8d, 0x18, 0x23, 0x13, - 0x30, 0x8c, 0x80, 0x91, 0x60, 0x06, 0x60, 0x2c, 0x01, 0x66, 0x08, 0xc6, - 0x4e, 0x7e, 0x91, 0xd2, 0xf5, 0x32, 0x66, 0xc7, 0x9d, 0x94, 0xbe, 0x2a, - 0x19, 0x9d, 0x0f, 0x24, 0x8a, 0x62, 0x6c, 0xc0, 0xa4, 0x14, 0xa2, 0x5e, - 0x39, 0x03, 0x16, 0xe6, 0x42, 0x54, 0xed, 0x70, 0xc0, 0xf8, 0x2c, 0x11, - 0x92, 0x8c, 0x06, 0x8c, 0xd0, 0x08, 0x8c, 0xaf, 0x19, 0x02, 0x46, 0x82, - 0x19, 0x80, 0xb1, 0x04, 0xbe, 0xe2, 0x90, 0x8d, 0xb0, 0x12, 0x66, 0x24, - 0x49, 0xec, 0xc8, 0x6e, 0x6c, 0x61, 0x77, 0x44, 0x45, 0x81, 0x74, 0x86, - 0x34, 0xb6, 0xf2, 0xc4, 0x9f, 0x80, 0x99, 0x93, 0x2a, 0xda, 0x13, 0xcc, - 0xb7, 0x5a, 0x72, 0x04, 0xd1, 0x69, 0x62, 0x4b, 0xd2, 0xfd, 0x18, 0xfe, - 0xd9, 0x2b, 0xe6, 0x6e, 0x3d, 0x9f, 0xe6, 0xad, 0x1f, 0xba, 0x7c, 0x6e, - 0x17, 0x89, 0x94, 0x63, 0x87, 0xc7, 0x6a, 0xa3, 0x5a, 0x6f, 0x1d, 0x6f, - 0x84, 0x52, 0xf5, 0x9f, 0xde, 0xbc, 0x19, 0x2b, 0x95, 0x39, 0xae, 0xbf, - 0x29, 0x96, 0xf3, 0x27, 0xc8, 0x75, 0x9d, 0x27, 0x9b, 0x0a, 0xc3, 0xec, - 0x74, 0x1c, 0x5c, 0x55, 0xeb, 0x47, 0xe4, 0xa0, 0x2e, 0x3f, 0x40, 0xf2, - 0xe1, 0xef, 0xf7, 0x5f, 0x5d, 0x5c, 0x1f, 0xaa, 0x45, 0x6b, 0x0b, 0xaf, - 0x28, 0xd5, 0xdb, 0xbf, 0xfe, 0x4a, 0x7f, 0x1c, 0x42, 0x5f, 0x50, 0x15, - 0x9a, 0x36, 0xa0, 0xd6, 0x5c, 0xcf, 0xff, 0x65, 0xfd, 0xc7, 0x8f, 0x09, - 0x28, 0x44, 0x20, 0x0d, 0x8d, 0x5c, 0x4b, 0x0c, 0x88, 0xd4, 0x34, 0x71, - 0x34, 0x1d, 0xd9, 0x5b, 0xea, 0x1b, 0xca, 0x88, 0xa6, 0xd0, 0x87, 0xa6, - 0xae, 0xa1, 0x34, 0x22, 0x4c, 0x9b, 0x56, 0xd5, 0x73, 0x63, 0xc0, 0x26, - 0x4c, 0x3b, 0x2e, 0x55, 0xfc, 0xed, 0xc1, 0xd9, 0x61, 0x5d, 0x76, 0x9e, - 0x54, 0xc4, 0x9e, 0xa5, 0x85, 0x96, 0xe6, 0x94, 0xc5, 0x69, 0x2e, 0x9b, - 0x60, 0xcc, 0x9f, 0x62, 0x12, 0x76, 0xac, 0x78, 0xa3, 0xca, 0x79, 0x70, - 0x90, 0x5e, 0x3a, 0xdb, 0x97, 0xc1, 0x83, 0x7c, 0x9a, 0xb8, 0xb6, 0x70, - 0x2c, 0xc8, 0x04, 0xb1, 0x03, 0xb8, 0x90, 0x2d, 0xb8, 0x96, 0x34, 0x00, - 0xed, 0xe0, 0x93, 0x11, 0x4b, 0x54, 0xac, 0x78, 0xe7, 0x5f, 0xe7, 0x65, - 0x7c, 0xe6, 0xc8, 0x83, 0x85, 0xa0, 0x91, 0x03, 0xc1, 0x85, 0x67, 0x35, - 0x54, 0xf0, 0x84, 0x91, 0x31, 0xf1, 0x2d, 0x41, 0xf1, 0x2c, 0x5c, 0x28, - 0x4d, 0x0e, 0xf2, 0xf5, 0xea, 0xb4, 0xf5, 0x44, 0x48, 0xb4, 0x4f, 0x7a, - 0xa4, 0xb5, 0x25, 0x4f, 0x42, 0xab, 0xfd, 0x41, 0xbe, 0x4e, 0x4a, 0xfb, - 0x6c, 0x28, 0xdf, 0x2e, 0x32, 0xe6, 0x8e, 0x24, 0x2c, 0x32, 0x74, 0x27, - 0x9b, 0x34, 0x63, 0x23, 0xb7, 0x3f, 0x41, 0x44, 0xc2, 0x3b, 0xe1, 0x1b, - 0x20, 0xaa, 0xec, 0xd0, 0x7a, 0x0d, 0x33, 0x52, 0xb1, 0x16, 0xc3, 0xab, - 0x92, 0xcb, 0xcd, 0x6e, 0x4a, 0x32, 0xb8, 0xa2, 0x69, 0xfc, 0xba, 0xec, - 0xc2, 0xb4, 0x81, 0xa8, 0x33, 0xc5, 0x5b, 0xff, 0x0a, 0xa2, 0x7e, 0x76, - 0x9a, 0x83, 0xbc, 0x8c, 0xc6, 0xa4, 0xb1, 0xcb, 0xb9, 0xf2, 0x3a, 0x75, - 0xbd, 0x9d, 0x0c, 0x73, 0x15, 0x77, 0x7c, 0x47, 0xa6, 0xf9, 0x5a, 0x9d, - 0x42, 0x8b, 0x61, 0xb4, 0x13, 0x20, 0x80, 0x39, 0x22, 0x08, 0x40, 0x13, - 0xb3, 0xc9, 0x27, 0x78, 0x4e, 0xf4, 0x59, 0x83, 0x0e, 0x1a, 0x3d, 0x85, - 0x0f, 0x10, 0x1c, 0x4a, 0xde, 0x5e, 0x2b, 0x58, 0x6e, 0xd1, 0x31, 0x19, - 0xce, 0x5a, 0x2e, 0x60, 0x9f, 0xa9, 0x5a, 0xb6, 0x5e, 0xa1, 0x4e, 0xf6, - 0x36, 0x8a, 0x36, 0xf7, 0x9e, 0xd0, 0xd6, 0x33, 0x96, 0xeb, 0x08, 0x87, - 0x49, 0x6e, 0x60, 0x12, 0x1f, 0x26, 0xbd, 0x7d, 0xda, 0x2f, 0x5d, 0xae, - 0x3a, 0x55, 0x29, 0xed, 0x48, 0xbb, 0x27, 0xac, 0x9d, 0xd6, 0xe6, 0x50, - 0x13, 0x78, 0x1e, 0x41, 0x31, 0x40, 0xa3, 0x22, 0xcd, 0x12, 0x20, 0x4a, - 0xf5, 0xf1, 0xe2, 0xed, 0x07, 0xf2, 0x87, 0x17, 0xf4, 0x58, 0x76, 0xde, - 0xe9, 0x52, 0x36, 0x43, 0x5b, 0x1c, 0x51, 0xe9, 0xd9, 0x0d, 0xb7, 0xc4, - 0x0b, 0xa2, 0x77, 0xd8, 0xf6, 0xff, 0x4a, 0xa2, 0x9f, 0xec, 0x28, 0x60, - 0x49, 0x47, 0x65, 0x68, 0x0b, 0x97, 0xcd, 0x36, 0x6d, 0xe7, 0xc5, 0x89, - 0xfc, 0xe9, 0x77, 0x78, 0x53, 0xdc, 0x86, 0x65, 0xb7, 0x29, 0xf9, 0x46, - 0xf5, 0xcd, 0x92, 0xf0, 0x55, 0xf8, 0x45, 0xeb, 0xcd, 0xa4, 0x0b, 0x87, - 0x45, 0x33, 0xdf, 0xec, 0x79, 0x3b, 0x21, 0x5e, 0x44, 0x20, 0x12, 0x5e, - 0xdf, 0x30, 0x6d, 0x3a, 0x0d, 0x25, 0x64, 0xe4, 0x93, 0xe1, 0x88, 0xc7, - 0xae, 0x57, 0x9c, 0x38, 0x9b, 0x8b, 0xe1, 0x68, 0x3d, 0x18, 0xbe, 0x7b, - 0x3f, 0xe0, 0x4b, 0xca, 0x8a, 0x59, 0xbc, 0x59, 0xa4, 0x8d, 0xc8, 0xdb, - 0xc9, 0xa4, 0x1b, 0x8d, 0xc2, 0xa1, 0x7e, 0xf0, 0x6a, 0x49, 0x87, 0xc5, - 0xf2, 0x62, 0xf2, 0xef, 0xce, 0x0d, 0x3d, 0x87, 0x33, 0x7a, 0x4c, 0xf0, - 0x62, 0xa0, 0x12, 0xbc, 0x01, 0x10, 0x30, 0xa1, 0xaa, 0x21, 0x0a, 0x2a, - 0x93, 0x84, 0x26, 0x54, 0xb0, 0xbb, 0x2a, 0x07, 0xd2, 0xd9, 0xd5, 0x89, - 0xe3, 0x0f, 0x7d, 0x77, 0x57, 0x51, 0x02, 0x90, 0xb0, 0x45, 0xed, 0xc2, - 0xce, 0x77, 0x1a, 0x54, 0x2c, 0xe3, 0x92, 0x2b, 0x5b, 0xc1, 0x29, 0x5a, - 0x79, 0x9d, 0x96, 0xc6, 0x63, 0x17, 0x20, 0x63, 0x8c, 0x32, 0xe5, 0x35, - 0x50, 0x7b, 0xc6, 0xfa, 0xc9, 0x96, 0xdf, 0x3a, 0x75, 0x5a, 0xaa, 0xf3, - 0x56, 0x15, 0x8a, 0xb0, 0x24, 0x4c, 0xe1, 0x34, 0xc1, 0x54, 0xbb, 0x10, - 0x6b, 0x3c, 0xa1, 0x66, 0x86, 0x18, 0x5f, 0xe8, 0x5d, 0xe2, 0x76, 0x12, - 0x84, 0xfb, 0x87, 0xf9, 0xba, 0x9c, 0xc3, 0xe2, 0x5e, 0xa4, 0xa8, 0xf2, - 0x60, 0x71, 0x1c, 0xe2, 0xc5, 0x23, 0x8b, 0x3f, 0x35, 0x08, 0x15, 0xdc, - 0x60, 0xdd, 0x12, 0x63, 0x69, 0xe9, 0x02, 0x93, 0x6f, 0x3b, 0x33, 0x95, - 0x3c, 0x98, 0x33, 0x8b, 0x1e, 0x2f, 0x35, 0x33, 0xf6, 0xc3, 0xa5, 0xba, - 0x23, 0x4c, 0x6c, 0x77, 0x72, 0x78, 0x4f, 0x5a, 0xd6, 0x6f, 0xe1, 0x4a, - 0xe9, 0x93, 0xc1, 0x1e, 0xec, 0x84, 0xf9, 0x7b, 0x79, 0x5d, 0x42, 0x47, - 0xff, 0xf4, 0x7e, 0x36, 0x7a, 0xe9, 0xd5, 0xf3, 0x80, 0xf4, 0xe5, 0xc9, - 0x67, 0x5b, 0x22, 0xd5, 0xd7, 0x05, 0xd8, 0x93, 0x8c, 0x81, 0x41, 0x06, - 0x75, 0x9e, 0x1c, 0xdc, 0x83, 0x40, 0x1d, 0xf7, 0xea, 0xac, 0x0d, 0xf3, - 0x8e, 0xc8, 0x3d, 0x71, 0xbd, 0x58, 0xcf, 0x32, 0x76, 0xe2, 0xb8, 0xae, - 0xdf, 0x6c, 0xf2, 0x75, 0x9a, 0xc5, 0x27, 0x2c, 0x70, 0x9a, 0x3d, 0x11, - 0x26, 0xca, 0xea, 0xec, 0x8e, 0x9e, 0xe9, 0xa1, 0x2b, 0xa7, 0x72, 0x93, - 0x17, 0xe9, 0x72, 0x19, 0xcf, 0xd9, 0x09, 0x77, 0x1d, 0x7f, 0x2c, 0x0f, - 0x45, 0xf0, 0x48, 0x25, 0x4f, 0x76, 0x46, 0xa1, 0x8d, 0xa5, 0x22, 0xde, - 0xd8, 0x2a, 0xf1, 0xda, 0x5d, 0x17, 0x76, 0x54, 0x09, 0x74, 0x9d, 0x08, - 0xff, 0xc5, 0x3a, 0xa9, 0xca, 0x41, 0x37, 0x29, 0xd7, 0xa6, 0x73, 0xba, - 0x69, 0x56, 0x7c, 0x54, 0xaf, 0xb2, 0xea, 0xa3, 0x7a, 0x9d, 0x55, 0x8d, - 0xe2, 0xf3, 0xcd, 0x6d, 0x67, 0x22, 0xa8, 0xe9, 0x10, 0xb7, 0x95, 0xdd, - 0x6e, 0xb5, 0x8b, 0xf3, 0x0d, 0x34, 0x2f, 0x14, 0x1c, 0xa5, 0x55, 0xd5, - 0x4d, 0x56, 0x9f, 0x5f, 0xaa, 0xd7, 0xe0, 0x56, 0xcb, 0x90, 0xb7, 0xa1, - 0x54, 0x29, 0x16, 0x18, 0x25, 0xe2, 0x0f, 0xd2, 0x4b, 0x26, 0xb7, 0xc6, - 0xcb, 0xef, 0x1b, 0xef, 0x19, 0x02, 0x37, 0xac, 0x55, 0xef, 0x86, 0x71, - 0xef, 0x86, 0x5f, 0x7b, 0x1e, 0x54, 0xac, 0xce, 0x6f, 0x54, 0xd6, 0xf8, - 0x7d, 0xc0, 0x72, 0xfb, 0x28, 0x65, 0x06, 0xe4, 0xff, 0xf9, 0xa6, 0x83, - 0x83, 0x8c, 0x38, 0x61, 0x13, 0x6c, 0x55, 0x03, 0xb2, 0xbc, 0x5e, 0xdc, - 0x9d, 0x3d, 0x73, 0xbe, 0xb8, 0xa7, 0xcf, 0xd7, 0xed, 0xd9, 0x7b, 0x82, - 0x48, 0x20, 0x7c, 0xaa, 0x83, 0xd1, 0x54, 0x83, 0x39, 0x6f, 0xf0, 0xf6, - 0x78, 0xc5, 0x8f, 0x48, 0x6b, 0x35, 0xb6, 0x64, 0x82, 0x47, 0x1e, 0xf2, - 0x85, 0x2b, 0x4c, 0x5e, 0xc2, 0x55, 0x45, 0x3d, 0xbb, 0xdc, 0x7a, 0x6c, - 0xbf, 0x69, 0x53, 0x58, 0xd4, 0xfc, 0xf6, 0xf6, 0x1b, 0x76, 0xf8, 0xd4, - 0x01, 0xe9, 0xbc, 0x26, 0x8c, 0x00, 0x33, 0x06, 0x93, 0x1a, 0xc7, 0xd7, - 0xd5, 0x20, 0x52, 0xe0, 0xf6, 0xc5, 0x0c, 0x9d, 0x5d, 0x9d, 0x38, 0x00, - 0x31, 0xb6, 0xab, 0x00, 0x35, 0xda, 0x57, 0x38, 0xdf, 0xae, 0x39, 0x52, - 0x3b, 0xad, 0xe3, 0x1f, 0x7d, 0xdd, 0x80, 0x9f, 0xa3, 0x7a, 0xe8, 0xd6, - 0xae, 0xbb, 0xbe, 0xdf, 0xce, 0x5e, 0x16, 0x9f, 0x5e, 0xa6, 0xba, 0xf1, - 0xbe, 0x35, 0xba, 0x2d, 0x1a, 0x76, 0x8c, 0x26, 0xef, 0x37, 0x78, 0x53, - 0x4d, 0x4f, 0x1c, 0xdf, 0x2f, 0x0a, 0xc4, 0x65, 0x57, 0x86, 0xc7, 0x1d, - 0xd5, 0x39, 0x25, 0xd4, 0x0a, 0xa3, 0x6b, 0x50, 0x83, 0xde, 0x43, 0x0b, - 0x93, 0x9e, 0xa8, 0x10, 0xad, 0x5d, 0x7f, 0x3f, 0x5f, 0xc7, 0x27, 0x03, - 0xfc, 0x4f, 0x36, 0xcc, 0xe7, 0xbe, 0x13, 0x38, 0xae, 0xe3, 0x8e, 0x5d, - 0x34, 0x30, 0xd8, 0x11, 0xd3, 0x15, 0x7b, 0xa1, 0xba, 0x0a, 0xfb, 0x3b, - 0x35, 0xac, 0x15, 0xda, 0x2e, 0xca, 0xb8, 0x34, 0x41, 0x1a, 0xe2, 0x1b, - 0x03, 0x48, 0xfe, 0x68, 0xf6, 0x0e, 0x34, 0xe4, 0x33, 0x45, 0x3f, 0x76, - 0xec, 0xc4, 0xa7, 0x64, 0x4b, 0x22, 0x4d, 0x5c, 0x4d, 0x2c, 0x43, 0x06, - 0x96, 0xd0, 0x84, 0x19, 0xe2, 0x6b, 0x62, 0x7c, 0xe3, 0x99, 0xa2, 0x1f, - 0x27, 0x70, 0xb0, 0x08, 0x8a, 0xb0, 0xbf, 0xd0, 0xb3, 0x81, 0x0f, 0x4c, - 0x11, 0xc0, 0x14, 0x8d, 0x28, 0x0e, 0x73, 0x35, 0xe4, 0x04, 0x46, 0xac, - 0xab, 0xf5, 0xfb, 0xd1, 0x7e, 0xfa, 0xc0, 0x53, 0x9d, 0xc6, 0xa4, 0xe7, - 0x21, 0x6b, 0xc3, 0x6a, 0x7d, 0xc9, 0xbf, 0x4a, 0x42, 0x0e, 0x8b, 0x5a, - 0xad, 0x94, 0x17, 0xec, 0x8e, 0xdb, 0xb4, 0x58, 0x9d, 0x76, 0x0a, 0xd9, - 0xc3, 0xf3, 0xc1, 0xa1, 0x85, 0xd2, 0xba, 0xba, 0x3e, 0xd5, 0x89, 0xe3, - 0x1c, 0x89, 0x63, 0x7c, 0x76, 0x97, 0x1e, 0xde, 0x03, 0xcf, 0x7b, 0xa8, - 0xb9, 0x5e, 0x19, 0xd4, 0x34, 0xf9, 0x8b, 0x4e, 0x63, 0x0e, 0x2b, 0x7c, - 0x37, 0xbc, 0x79, 0x20, 0xcc, 0x93, 0x04, 0xe7, 0x6c, 0x05, 0x09, 0xdb, - 0x43, 0x69, 0x82, 0xdf, 0xdd, 0xb6, 0x0e, 0xcc, 0x73, 0x63, 0x8e, 0xce, - 0x04, 0xbf, 0x3e, 0xef, 0x8a, 0xe1, 0x4e, 0xd3, 0x6a, 0xad, 0x21, 0x4b, - 0xd0, 0x74, 0xd3, 0x06, 0x0e, 0x9d, 0xeb, 0x45, 0x1b, 0xe1, 0x3b, 0xf4, - 0xf8, 0x5b, 0x5d, 0xc4, 0x03, 0xa5, 0x55, 0x01, 0xd4, 0x78, 0x56, 0x96, - 0x6c, 0x2b, 0x8b, 0xde, 0xc3, 0x34, 0x5d, 0x23, 0x2c, 0xc3, 0x11, 0x77, - 0xba, 0xab, 0x20, 0xa8, 0x52, 0xe9, 0xf7, 0x02, 0x6b, 0x3f, 0x40, 0xca, - 0x4e, 0x1e, 0x86, 0x22, 0x89, 0x3b, 0x82, 0x20, 0xec, 0x1b, 0x77, 0x83, - 0xe0, 0x4a, 0xad, 0x3e, 0xdf, 0x25, 0xa9, 0xdb, 0xd4, 0x00, 0x69, 0x03, - 0xd7, 0x37, 0x8b, 0x6c, 0xee, 0xee, 0x49, 0x0d, 0x3a, 0x8d, 0x87, 0x44, - 0x54, 0x63, 0x8f, 0xc4, 0x71, 0xc1, 0xad, 0x23, 0xd0, 0x54, 0xc3, 0x5a, - 0x98, 0x3c, 0x8e, 0x7d, 0x55, 0x5e, 0xad, 0xb2, 0xd2, 0xb0, 0x0d, 0x12, - 0x48, 0x08, 0x37, 0x6b, 0x1d, 0x26, 0xfd, 0xff, 0x91, 0x75, 0xab, 0xf5, - 0xf9, 0x39, 0xde, 0x15, 0x7f, 0x7f, 0xf3, 0x66, 0x80, 0xfc, 0x3e, 0x9c, - 0xdd, 0x83, 0xd4, 0x6f, 0xba, 0xc1, 0xe5, 0x9d, 0x45, 0xab, 0xe5, 0x39, - 0x82, 0x84, 0x9a, 0x7f, 0x27, 0x8b, 0xc1, 0x6d, 0x43, 0x21, 0xca, 0x1c, - 0xdd, 0x86, 0x0f, 0xa7, 0x37, 0xef, 0x73, 0xae, 0xb6, 0x25, 0xfe, 0x61, - 0x5d, 0xab, 0x4c, 0xf1, 0x9d, 0xa7, 0x5a, 0xb2, 0xba, 0xc6, 0xa6, 0x96, - 0xb3, 0x85, 0xc0, 0x16, 0x1d, 0x46, 0x1f, 0x31, 0x84, 0x23, 0xd3, 0xba, - 0x42, 0xf4, 0xf0, 0xcd, 0xfd, 0xa6, 0x5e, 0x7e, 0x26, 0xfa, 0x7a, 0x12, - 0x1d, 0x99, 0x5b, 0x4a, 0x74, 0x98, 0x97, 0xfd, 0xd1, 0xa8, 0x4b, 0xdc, - 0xb2, 0x16, 0x2d, 0x19, 0xb3, 0x99, 0x68, 0xc6, 0x4c, 0xbb, 0x65, 0x66, - 0xb8, 0x27, 0x3b, 0xdc, 0x2d, 0x52, 0xf9, 0x5f, 0xe0, 0xff, 0x61, 0x05, - 0xb9, 0x4b, 0x0e, 0x10, 0x35, 0x31, 0x0b, 0x5a, 0x05, 0x52, 0x0e, 0xfd, - 0x7d, 0xdc, 0x75, 0x06, 0x80, 0xd6, 0x2a, 0xbd, 0xc0, 0x65, 0x47, 0x54, - 0xc7, 0x97, 0xd4, 0xe7, 0x02, 0x77, 0x22, 0x8a, 0xab, 0x91, 0xb9, 0x21, - 0x01, 0xec, 0xfc, 0x30, 0x4e, 0xdb, 0x31, 0xcf, 0x65, 0xcd, 0xe2, 0x4f, - 0xc1, 0xab, 0x34, 0xbf, 0xe0, 0xef, 0xa7, 0x5f, 0xde, 0x5e, 0xac, 0x4f, - 0xde, 0xb9, 0xd5, 0xdf, 0x8b, 0xbf, 0x65, 0xc3, 0x7f, 0x4c, 0xd6, 0xaf, - 0xe3, 0xfd, 0x2f, 0xaf, 0xdf, 0xe7, 0x5f, 0xde, 0xb1, 0xe2, 0x53, 0xf8, - 0x32, 0x6d, 0x3a, 0x08, 0x1a, 0x70, 0x5b, 0x34, 0x9c, 0x26, 0xcd, 0x98, - 0x2e, 0xe4, 0x98, 0x1d, 0x8b, 0x80, 0x20, 0x58, 0xe2, 0xc3, 0xae, 0x6f, - 0xbe, 0xb8, 0xfd, 0x94, 0xfe, 0x46, 0x9f, 0xa1, 0x9a, 0x0f, 0x9b, 0x00, - 0x69, 0xae, 0xc4, 0x99, 0xf6, 0xe2, 0x00, 0x70, 0xae, 0x68, 0xd7, 0x8b, - 0xac, 0x49, 0x1a, 0x33, 0x23, 0x32, 0x10, 0x7f, 0x28, 0xde, 0x1e, 0x5f, - 0xd0, 0x4f, 0x78, 0x4f, 0xa4, 0xdf, 0xb3, 0x15, 0xd9, 0xdc, 0x81, 0xcc, - 0xab, 0x49, 0x58, 0xde, 0xa8, 0x73, 0xe9, 0xd0, 0x64, 0xfb, 0xb3, 0x93, - 0x66, 0xf7, 0xe3, 0x80, 0x5f, 0xf3, 0x33, 0x18, 0xa1, 0xb1, 0xe0, 0xe8, - 0xe1, 0xb9, 0x6f, 0x8e, 0x3c, 0xa8, 0xb9, 0x63, 0x5f, 0x61, 0xc1, 0xa2, - 0xf5, 0x68, 0xf2, 0xe8, 0xb0, 0x20, 0x0f, 0xf3, 0xd8, 0x02, 0xfb, 0x7c, - 0xb0, 0x9a, 0xcf, 0x64, 0xe0, 0xf1, 0xe5, 0x83, 0x39, 0x58, 0x16, 0x86, - 0x23, 0x0e, 0x3d, 0xad, 0x56, 0xf0, 0xb9, 0x52, 0xe5, 0xb6, 0xf8, 0x0f, - 0x50, 0xdd, 0x7d, 0xcc, 0xa9, 0x11, 0x00, 0x00 -}; +const uint8_t Antonio_SemiBold20pt7bBitmaps[] PROGMEM = { + 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x66, 0x66, 0x66, + 0x66, 0x66, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xEF, 0x7B, 0xDE, 0xF7, + 0x98, 0xC6, 0x00, 0x03, 0x8F, 0x01, 0xC7, 0x80, 0xE3, 0x80, 0xF1, 0xC0, + 0x70, 0xE0, 0x38, 0x70, 0x1C, 0x78, 0x0E, 0x3C, 0x07, 0x1C, 0x07, 0x8E, + 0x03, 0x87, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x38, 0xE0, 0x3C, + 0x70, 0x1E, 0x38, 0x0E, 0x1C, 0x07, 0x0E, 0x03, 0x8F, 0x0F, 0xFF, 0xF7, + 0xFF, 0xF8, 0xF1, 0xC0, 0x70, 0xE0, 0x38, 0x70, 0x1C, 0x78, 0x0E, 0x3C, + 0x0F, 0x1C, 0x07, 0x8E, 0x03, 0x87, 0x01, 0xC3, 0x80, 0xE3, 0xC0, 0x71, + 0xE0, 0x78, 0xE0, 0x00, 0x06, 0x00, 0x30, 0x01, 0x80, 0x0C, 0x00, 0x60, + 0x1F, 0xC1, 0xFF, 0x9F, 0xFC, 0xFB, 0xF7, 0x87, 0xBC, 0x3D, 0xE1, 0xEF, + 0x0F, 0x78, 0x7B, 0xE3, 0xDF, 0x00, 0x7C, 0x01, 0xF8, 0x0F, 0xE0, 0x3F, + 0x80, 0x7C, 0x01, 0xF0, 0x07, 0xC0, 0x3E, 0xF0, 0xF7, 0x87, 0xFC, 0x3F, + 0xE1, 0xFF, 0x0F, 0xFC, 0x7B, 0xFF, 0xCF, 0xFE, 0x3F, 0xE0, 0xFE, 0x01, + 0xC0, 0x0E, 0x00, 0x70, 0x03, 0x80, 0x1C, 0x00, 0x1F, 0x80, 0x01, 0xC0, + 0x07, 0xFE, 0x00, 0x3C, 0x00, 0x7F, 0xE0, 0x03, 0xC0, 0x0F, 0x9F, 0x00, + 0x38, 0x00, 0xF0, 0xF0, 0x07, 0x80, 0x0F, 0x0F, 0x00, 0x70, 0x00, 0xF0, + 0xF0, 0x0F, 0x00, 0x0F, 0x0F, 0x00, 0xF0, 0x00, 0xF0, 0xF0, 0x0E, 0x00, + 0x0F, 0x0F, 0x01, 0xE0, 0x00, 0xF0, 0xF0, 0x1C, 0x00, 0x0F, 0x0F, 0x03, + 0xC0, 0x60, 0xF0, 0xF0, 0x3C, 0x3F, 0xCF, 0x0F, 0x03, 0x87, 0xFE, 0xF0, + 0xF0, 0x78, 0xFF, 0xEF, 0x0F, 0x07, 0x8F, 0x0E, 0xF0, 0xF0, 0xF0, 0xF0, + 0xFF, 0x0F, 0x0F, 0x0E, 0x0F, 0xF0, 0xF0, 0xE0, 0xE0, 0xF7, 0xDF, 0x1E, + 0x0E, 0x0F, 0x7F, 0xE1, 0xE0, 0xE0, 0xF3, 0xFC, 0x1C, 0x0E, 0x0F, 0x1F, + 0x83, 0xC0, 0xE0, 0xF0, 0x00, 0x38, 0x0E, 0x0F, 0x00, 0x07, 0x80, 0xE0, + 0xF0, 0x00, 0x78, 0x0E, 0x0F, 0x00, 0x07, 0x00, 0xE0, 0xF0, 0x00, 0xF0, + 0x0E, 0x0F, 0x00, 0x0E, 0x00, 0xE0, 0xF0, 0x01, 0xE0, 0x0F, 0x0F, 0x00, + 0x1E, 0x00, 0xF1, 0xE0, 0x01, 0xC0, 0x0F, 0xFE, 0x00, 0x3C, 0x00, 0x7F, + 0xC0, 0x03, 0x80, 0x03, 0xF8, 0x03, 0xE0, 0x03, 0xFE, 0x00, 0xFF, 0x80, + 0x7C, 0xF0, 0x1E, 0x1C, 0x07, 0x87, 0x01, 0xE1, 0xC0, 0x78, 0x70, 0x1E, + 0x1C, 0x07, 0x8F, 0x00, 0xF3, 0x80, 0x3D, 0xE0, 0x0F, 0x78, 0x01, 0xFC, + 0x00, 0x7E, 0x00, 0x1F, 0x80, 0x07, 0xC0, 0x03, 0xF0, 0x00, 0xFE, 0x08, + 0x7F, 0x86, 0x3F, 0xE3, 0x8F, 0x3C, 0xF7, 0x8F, 0x79, 0xE1, 0xFC, 0x78, + 0x7F, 0x3C, 0x1F, 0x8F, 0x03, 0xE3, 0xC0, 0xF0, 0xF0, 0x3E, 0x1E, 0x1F, + 0x87, 0xFF, 0xF1, 0xFF, 0xFC, 0x3F, 0xE7, 0x87, 0xF1, 0xE0, 0xFF, 0xFF, + 0xF7, 0x76, 0x66, 0x66, 0x3E, 0xFF, 0xFF, 0xCF, 0x1E, 0x3C, 0x78, 0xF1, + 0xE3, 0xC7, 0x8F, 0x1E, 0x3C, 0x78, 0xF1, 0xE3, 0xC7, 0x8F, 0x1E, 0x3C, + 0x78, 0xF1, 0xE3, 0xC7, 0x8F, 0x1E, 0x3C, 0x78, 0xF1, 0xE3, 0xFB, 0xF7, + 0xE1, 0xC0, 0xF1, 0xF3, 0xF1, 0xE3, 0xC7, 0xCF, 0x9F, 0x3E, 0x7C, 0xF9, + 0xF3, 0xE7, 0xCF, 0x9F, 0x3E, 0x7C, 0xF9, 0xF3, 0xE7, 0xCF, 0x9F, 0x3E, + 0x7C, 0xF9, 0xF3, 0xE7, 0xCF, 0x9F, 0x3E, 0x7B, 0xF7, 0xEF, 0x98, 0x00, + 0x07, 0x00, 0x1C, 0x04, 0x71, 0x39, 0xCE, 0xFB, 0x7D, 0xFF, 0xC1, 0xFC, + 0x03, 0xE0, 0x3F, 0xE3, 0xEF, 0xFF, 0x73, 0x99, 0xC6, 0x07, 0x08, 0x1C, + 0x00, 0x70, 0x00, 0x0F, 0x00, 0xF0, 0x0F, 0x00, 0xF0, 0xFF, 0xFF, 0xFF, + 0xFF, 0xF0, 0xF0, 0x0F, 0x00, 0xF0, 0x0F, 0x00, 0xF0, 0xFF, 0xFF, 0xFF, + 0x8C, 0xE7, 0x31, 0x9C, 0xC0, 0xFF, 0xFF, 0xFF, 0xE0, 0xFF, 0xFF, 0x00, + 0xF8, 0x07, 0x80, 0x3C, 0x01, 0xE0, 0x0E, 0x00, 0xF0, 0x07, 0x80, 0x3C, + 0x01, 0xC0, 0x1E, 0x00, 0xF0, 0x07, 0x80, 0x38, 0x03, 0xC0, 0x1E, 0x00, + 0xF0, 0x07, 0x80, 0x78, 0x03, 0xC0, 0x1E, 0x00, 0xF0, 0x0F, 0x00, 0x78, + 0x03, 0xC0, 0x1E, 0x01, 0xE0, 0x0F, 0x00, 0x78, 0x03, 0xC0, 0x3C, 0x01, + 0xE0, 0x0F, 0x00, 0x78, 0x07, 0x80, 0x00, 0x0F, 0xC1, 0xFF, 0x9F, 0xFC, + 0xFF, 0xF7, 0x8F, 0xFC, 0x3F, 0xE1, 0xFF, 0x0F, 0xF8, 0x7F, 0xC3, 0xFE, + 0x1F, 0xF0, 0xFF, 0x87, 0xFC, 0x3F, 0xE1, 0xFF, 0x0F, 0xF8, 0x7F, 0xC3, + 0xFE, 0x1F, 0xF0, 0xFF, 0x87, 0xFC, 0x3F, 0xE1, 0xFF, 0x0F, 0xF8, 0x7F, + 0xC3, 0xFE, 0x1F, 0xF0, 0xFF, 0x87, 0xBC, 0x7D, 0xF7, 0xEF, 0xFE, 0x3F, + 0xF0, 0xFF, 0x00, 0x03, 0x83, 0xC3, 0xE3, 0xFF, 0xFF, 0xFF, 0xFF, 0x9F, + 0x0F, 0x87, 0xC3, 0xE1, 0xF0, 0xF8, 0x7C, 0x3E, 0x1F, 0x0F, 0x87, 0xC3, + 0xE1, 0xF0, 0xF8, 0x7C, 0x3E, 0x1F, 0x0F, 0x87, 0xC3, 0xE1, 0xF0, 0xF8, + 0x7C, 0x3E, 0x1F, 0x0F, 0x87, 0xC0, 0x0F, 0x81, 0xFF, 0x1F, 0xF8, 0xFF, + 0xEF, 0x8F, 0x7C, 0x7B, 0xC3, 0xDE, 0x1E, 0xF0, 0xFF, 0x87, 0xFC, 0x3F, + 0xE1, 0xEF, 0x0F, 0x78, 0x78, 0x07, 0xC0, 0x3C, 0x03, 0xE0, 0x1E, 0x01, + 0xF0, 0x0F, 0x00, 0xF8, 0x07, 0x80, 0x7C, 0x07, 0xC0, 0x3E, 0x03, 0xE0, + 0x1F, 0x00, 0xF0, 0x07, 0x80, 0x7C, 0x03, 0xE0, 0x1F, 0xFE, 0xFF, 0xF7, + 0xFF, 0x80, 0x0F, 0xC0, 0xFF, 0x87, 0xFF, 0x1F, 0xFE, 0x78, 0xFB, 0xE1, + 0xEF, 0x87, 0xBC, 0x1E, 0xF0, 0x7B, 0xC1, 0xE0, 0x07, 0x80, 0x1E, 0x00, + 0x78, 0x03, 0xE0, 0x3F, 0x01, 0xF8, 0x07, 0xE0, 0x1F, 0xC0, 0x0F, 0x00, + 0x3E, 0x00, 0x78, 0x01, 0xE0, 0x07, 0xBC, 0x1E, 0xF0, 0x7F, 0xC1, 0xFF, + 0x07, 0xBC, 0x1E, 0xF0, 0x7B, 0xE1, 0xE7, 0xDF, 0x9F, 0xFC, 0x3F, 0xE0, + 0x7F, 0x00, 0x01, 0xF0, 0x07, 0xC0, 0x3F, 0x00, 0xFC, 0x03, 0xF0, 0x1F, + 0xC0, 0x7F, 0x01, 0xFC, 0x06, 0xF0, 0x3B, 0xC0, 0xEF, 0x03, 0xBC, 0x1C, + 0xF0, 0x73, 0xC1, 0xCF, 0x0F, 0x3C, 0x38, 0xF0, 0xE3, 0xC7, 0x8F, 0x1C, + 0x3C, 0x70, 0xF1, 0xC3, 0xCF, 0x0F, 0x38, 0x3C, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0x00, 0xF0, 0x03, 0xC0, 0x0F, 0x00, 0x3C, 0x00, 0xF0, + 0x03, 0xC0, 0xFF, 0xEF, 0xFE, 0xFF, 0xEF, 0xFE, 0xF0, 0x0F, 0x00, 0xF0, + 0x0F, 0x00, 0xF0, 0x0F, 0x00, 0xF3, 0x0F, 0xFC, 0xFF, 0xEF, 0xFE, 0xF9, + 0xEF, 0x1F, 0xF0, 0xF1, 0x0F, 0x00, 0xF0, 0x0F, 0x00, 0xF0, 0x0F, 0x00, + 0xF0, 0x0F, 0xF0, 0xFF, 0x0F, 0xF0, 0xFF, 0x0F, 0xF0, 0xFF, 0x1F, 0xFB, + 0xEF, 0xFE, 0x7F, 0xC3, 0xF8, 0x0F, 0xC0, 0xFF, 0x83, 0xFF, 0x1F, 0xFC, + 0x78, 0xF9, 0xE1, 0xEF, 0x87, 0xBE, 0x1E, 0xF8, 0x7B, 0xE1, 0xEF, 0x80, + 0x3E, 0x00, 0xF8, 0x03, 0xEF, 0x8F, 0xFF, 0x3F, 0xFE, 0xFF, 0xFB, 0xE1, + 0xEF, 0x87, 0xBE, 0x1E, 0xF8, 0x7F, 0xE1, 0xFF, 0x87, 0xFE, 0x1F, 0xF8, + 0x7F, 0xE1, 0xFF, 0x87, 0xFE, 0x1F, 0xF8, 0x79, 0xE1, 0xE7, 0xFF, 0x9F, + 0xFE, 0x3F, 0xF0, 0x7F, 0x80, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0x00, 0x7C, 0x01, 0xE0, 0x0F, 0x80, 0x3C, 0x00, 0xF0, 0x07, 0xC0, 0x1E, + 0x00, 0x78, 0x03, 0xE0, 0x0F, 0x80, 0x3C, 0x00, 0xF0, 0x07, 0xC0, 0x1E, + 0x00, 0x78, 0x03, 0xE0, 0x0F, 0x80, 0x3C, 0x00, 0xF0, 0x07, 0xC0, 0x1F, + 0x00, 0x7C, 0x01, 0xF0, 0x07, 0x80, 0x1E, 0x00, 0xF8, 0x03, 0xE0, 0x0F, + 0x80, 0x3E, 0x00, 0xF8, 0x00, 0x1F, 0xC1, 0xFF, 0x1F, 0xFC, 0xFB, 0xFF, + 0x8F, 0xFC, 0x3F, 0xC1, 0xFE, 0x0F, 0xF0, 0x7F, 0x83, 0xFC, 0x1F, 0xE0, + 0xFF, 0x87, 0xBC, 0x79, 0xFF, 0xC7, 0xFC, 0x3F, 0xE3, 0xFF, 0x9E, 0x3D, + 0xF1, 0xFF, 0x07, 0xF8, 0x3F, 0xC1, 0xFE, 0x0F, 0xF0, 0x7F, 0x83, 0xFC, + 0x1F, 0xE0, 0xFF, 0x07, 0xFC, 0x3F, 0xF7, 0xEF, 0xFE, 0x3F, 0xF0, 0xFE, + 0x00, 0x1F, 0x81, 0xFF, 0x1F, 0xFD, 0xFF, 0xEF, 0x8F, 0x78, 0x7F, 0xC3, + 0xFE, 0x0F, 0xF0, 0x7F, 0x83, 0xFC, 0x1F, 0xE0, 0xFF, 0x07, 0xF8, 0x3F, + 0xC1, 0xFE, 0x0F, 0xF0, 0x7F, 0xC7, 0xDF, 0xFE, 0xFF, 0xF3, 0xFF, 0x80, + 0x3C, 0x01, 0xE0, 0x0F, 0xF0, 0x7F, 0x83, 0xFC, 0x1F, 0xE0, 0xFF, 0x0F, + 0xFC, 0x79, 0xF7, 0xCF, 0xFE, 0x3F, 0xE0, 0xFE, 0x00, 0xFF, 0xFF, 0xF0, + 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xFF, 0xF3, 0x9C, 0xCE, 0x73, 0x98, + 0x00, 0x20, 0x0C, 0x07, 0x81, 0xF0, 0xFE, 0x3F, 0x9F, 0xC7, 0xF0, 0xF8, + 0x1C, 0x03, 0xE0, 0x7E, 0x07, 0xF0, 0x3F, 0x03, 0xF8, 0x1F, 0x01, 0xE0, + 0x0C, 0x00, 0x80, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x0F, 0xFF, + 0xFF, 0xFF, 0xC0, 0x80, 0x18, 0x03, 0x80, 0x7C, 0x0F, 0xC0, 0xFE, 0x07, + 0xF0, 0x7F, 0x03, 0xE0, 0x3C, 0x0F, 0x83, 0xF1, 0xFC, 0xFE, 0x3F, 0x87, + 0xC0, 0xF0, 0x18, 0x02, 0x00, 0x00, 0x1F, 0x87, 0xFC, 0x7F, 0xEF, 0xFE, + 0xF1, 0xEF, 0x1F, 0xF1, 0xFF, 0x1F, 0xF1, 0xFF, 0x1F, 0xF1, 0xFF, 0x1F, + 0x01, 0xF0, 0x1E, 0x01, 0xE0, 0x3E, 0x03, 0xE0, 0xFC, 0x3F, 0x83, 0xF0, + 0x3C, 0x03, 0xC0, 0x3C, 0x03, 0xC0, 0x3C, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x3C, 0x03, 0xC0, 0x3C, 0x03, 0xC0, 0x3C, 0x03, 0xC0, 0x00, 0x3F, 0x80, + 0x00, 0xFF, 0xF0, 0x00, 0xFF, 0xFC, 0x00, 0xF8, 0x0F, 0x00, 0xF0, 0x03, + 0xC0, 0xF0, 0x00, 0xF0, 0xF0, 0x00, 0x38, 0x78, 0x00, 0x1C, 0x38, 0x1F, + 0x87, 0x3C, 0x3F, 0xE3, 0x9E, 0x1E, 0xF1, 0xCE, 0x1C, 0x38, 0xE7, 0x0E, + 0x1C, 0x77, 0x8E, 0x0E, 0x1F, 0xC7, 0x07, 0x0F, 0xE3, 0x83, 0x87, 0xF1, + 0xC1, 0xC3, 0xF8, 0xE0, 0xE1, 0xFC, 0x70, 0x70, 0xFE, 0x38, 0x38, 0x7F, + 0x1C, 0x1C, 0x77, 0x8E, 0x0E, 0x39, 0xC7, 0x07, 0x1C, 0xE3, 0xC7, 0xCE, + 0x70, 0xF6, 0xFE, 0x3C, 0x7F, 0x3F, 0x1E, 0x1F, 0x0F, 0x07, 0x81, 0x00, + 0x03, 0xC0, 0x00, 0x00, 0xF0, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x1F, 0x80, + 0x70, 0x07, 0xFF, 0xF8, 0x00, 0xFF, 0xFE, 0x00, 0x1F, 0xF0, 0x00, 0x07, + 0xC0, 0x07, 0xE0, 0x0F, 0xE0, 0x0F, 0xE0, 0x0F, 0xE0, 0x0F, 0xE0, 0x0F, + 0xE0, 0x0F, 0xF0, 0x0E, 0xF0, 0x1E, 0xF0, 0x1E, 0xF0, 0x1E, 0xF0, 0x1E, + 0xF0, 0x1E, 0x70, 0x1E, 0x78, 0x1C, 0x78, 0x3C, 0x78, 0x3C, 0x78, 0x3C, + 0x78, 0x3C, 0x78, 0x3C, 0x3C, 0x3C, 0x3C, 0x7C, 0x3C, 0x78, 0x3C, 0x7F, + 0xFC, 0x7F, 0xFC, 0x7F, 0xFE, 0x7F, 0xFE, 0x78, 0x1E, 0xF8, 0x1E, 0xF8, + 0x1E, 0xF0, 0x1E, 0xF0, 0x1F, 0xF0, 0x1F, 0xFF, 0x03, 0xFF, 0x8F, 0xFF, + 0x3F, 0xFC, 0xF0, 0xFB, 0xC3, 0xEF, 0x07, 0xBC, 0x1E, 0xF0, 0x7B, 0xC1, + 0xEF, 0x07, 0xBC, 0x3E, 0xF0, 0xFB, 0xC3, 0xCF, 0xFF, 0x3F, 0xF8, 0xFF, + 0xF3, 0xFF, 0xCF, 0x0F, 0xBC, 0x1E, 0xF0, 0x7B, 0xC1, 0xEF, 0x07, 0xFC, + 0x1F, 0xF0, 0x7F, 0xC1, 0xFF, 0x07, 0xBC, 0x1E, 0xF0, 0x7B, 0xC3, 0xEF, + 0xFF, 0xBF, 0xFC, 0xFF, 0xE3, 0xFF, 0x00, 0x0F, 0xC0, 0x7F, 0xC3, 0xFF, + 0x9F, 0xFE, 0x7C, 0x79, 0xE1, 0xFF, 0x87, 0xFE, 0x0F, 0xF8, 0x3F, 0xE0, + 0xFF, 0x83, 0xFE, 0x0F, 0xF8, 0x3F, 0xE0, 0x0F, 0x80, 0x3E, 0x00, 0xF8, + 0x03, 0xE0, 0x0F, 0x80, 0x3E, 0x00, 0xF8, 0x3F, 0xE0, 0xFF, 0x83, 0xFE, + 0x0F, 0xF8, 0x3F, 0xE0, 0xFF, 0x83, 0xFE, 0x1F, 0x78, 0x7D, 0xE1, 0xE7, + 0xEF, 0x8F, 0xFE, 0x3F, 0xF0, 0x3F, 0x80, 0xFF, 0x07, 0xFF, 0x3F, 0xFD, + 0xFF, 0xEF, 0x0F, 0xF8, 0x7F, 0xC1, 0xFE, 0x0F, 0xF0, 0x7F, 0x83, 0xFC, + 0x1F, 0xE0, 0xFF, 0x07, 0xF8, 0x3F, 0xC1, 0xFE, 0x0F, 0xF0, 0x7F, 0x83, + 0xFC, 0x1F, 0xE0, 0xFF, 0x07, 0xF8, 0x3F, 0xC1, 0xFE, 0x0F, 0xF0, 0x7F, + 0x83, 0xFC, 0x1F, 0xE0, 0xFF, 0x07, 0xF8, 0x7F, 0xFF, 0xDF, 0xFE, 0xFF, + 0xE7, 0xFC, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x3C, 0x0F, 0x03, + 0xC0, 0xF0, 0x3C, 0x0F, 0x03, 0xC0, 0xF0, 0x3C, 0x0F, 0x03, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xC0, 0xF0, 0x3C, 0x0F, 0x03, 0xC0, 0xF0, 0x3C, 0x0F, + 0x03, 0xC0, 0xF0, 0x3C, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xF0, 0x3C, 0x0F, 0x03, 0xC0, 0xF0, 0x3C, 0x0F, 0x03, + 0xC0, 0xF0, 0x3C, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x03, 0xC0, 0xF0, + 0x3C, 0x0F, 0x03, 0xC0, 0xF0, 0x3C, 0x0F, 0x03, 0xC0, 0xF0, 0x3C, 0x0F, + 0x03, 0xC0, 0xF0, 0x3C, 0x00, 0x0F, 0xE0, 0x7F, 0xC3, 0xFF, 0x9F, 0xFE, + 0x7C, 0x7D, 0xE0, 0xFF, 0x83, 0xFE, 0x0F, 0xF8, 0x3F, 0xE0, 0xFF, 0x83, + 0xFE, 0x0F, 0xF8, 0x03, 0xE0, 0x0F, 0x80, 0x3E, 0x00, 0xF9, 0xFF, 0xE7, + 0xFF, 0x9F, 0xFE, 0x0F, 0xF8, 0x3F, 0xE0, 0xFF, 0x83, 0xFE, 0x0F, 0xF8, + 0x3F, 0xE0, 0xFF, 0x83, 0xFE, 0x0F, 0x78, 0x3D, 0xE1, 0xF7, 0xEF, 0xCF, + 0xFF, 0x3F, 0xEC, 0x3F, 0x30, 0xF0, 0x7F, 0xC1, 0xFF, 0x07, 0xFC, 0x1F, + 0xF0, 0x7F, 0xC1, 0xFF, 0x07, 0xFC, 0x1F, 0xF0, 0x7F, 0xC1, 0xFF, 0x07, + 0xFC, 0x1F, 0xF0, 0x7F, 0xC1, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0x07, 0xFC, 0x1F, 0xF0, 0x7F, 0xC1, 0xFF, 0x07, 0xFC, 0x1F, 0xF0, + 0x7F, 0xC1, 0xFF, 0x07, 0xFC, 0x1F, 0xF0, 0x7F, 0xC1, 0xFF, 0x07, 0xFC, + 0x1F, 0xF0, 0x7F, 0xC1, 0xF0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xF8, + 0x07, 0xC0, 0x3E, 0x01, 0xF0, 0x0F, 0x80, 0x7C, 0x03, 0xE0, 0x1F, 0x00, + 0xF8, 0x07, 0xC0, 0x3E, 0x01, 0xF0, 0x0F, 0x80, 0x7C, 0x03, 0xE0, 0x1F, + 0x00, 0xF8, 0x07, 0xC0, 0x3E, 0x01, 0xF0, 0x0F, 0xF8, 0x7F, 0xC3, 0xFE, + 0x1F, 0xF0, 0xFF, 0x87, 0xFC, 0x3F, 0xE1, 0xEF, 0x0F, 0x78, 0x7B, 0xF7, + 0xCF, 0xFC, 0x7F, 0xE1, 0xFE, 0x00, 0xF0, 0x3D, 0xE0, 0xFB, 0xC1, 0xE7, + 0x83, 0xCF, 0x0F, 0x9E, 0x1E, 0x3C, 0x3C, 0x78, 0xF8, 0xF1, 0xE1, 0xE7, + 0xC3, 0xCF, 0x87, 0x9E, 0x0F, 0x7C, 0x1E, 0xF8, 0x3D, 0xE0, 0x7F, 0xC0, + 0xFF, 0x01, 0xFE, 0x03, 0xFE, 0x07, 0xBC, 0x0F, 0x7C, 0x1E, 0xF8, 0x3C, + 0xF0, 0x79, 0xF0, 0xF1, 0xE1, 0xE3, 0xC3, 0xC7, 0xC7, 0x87, 0x8F, 0x0F, + 0x9E, 0x1F, 0x3C, 0x1E, 0x78, 0x3E, 0xF0, 0x7D, 0xE0, 0x7C, 0xF0, 0x3C, + 0x0F, 0x03, 0xC0, 0xF0, 0x3C, 0x0F, 0x03, 0xC0, 0xF0, 0x3C, 0x0F, 0x03, + 0xC0, 0xF0, 0x3C, 0x0F, 0x03, 0xC0, 0xF0, 0x3C, 0x0F, 0x03, 0xC0, 0xF0, + 0x3C, 0x0F, 0x03, 0xC0, 0xF0, 0x3C, 0x0F, 0x03, 0xC0, 0xF0, 0x3C, 0x0F, + 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0xF8, 0x01, 0xFF, 0x80, 0x1F, 0xF8, 0x03, + 0xFF, 0xC0, 0x3F, 0xFC, 0x03, 0xFF, 0xC0, 0x3F, 0xFC, 0x03, 0xFF, 0xC0, + 0x7F, 0xFE, 0x07, 0xFF, 0xE0, 0x7F, 0xFE, 0x07, 0xFE, 0xE0, 0x7F, 0xEE, + 0x0F, 0xFE, 0xF0, 0xFF, 0xEF, 0x0E, 0xFE, 0x70, 0xEF, 0xE7, 0x0E, 0xFE, + 0x70, 0xEF, 0xE7, 0x1E, 0xFE, 0x79, 0xCF, 0xE3, 0x9C, 0xFF, 0x39, 0xCF, + 0xF3, 0x9C, 0xFF, 0x3B, 0xCF, 0xF3, 0xF8, 0xFF, 0x1F, 0x8F, 0xF1, 0xF8, + 0xFF, 0x1F, 0x8F, 0xF1, 0xF8, 0xFF, 0x1F, 0x8F, 0xF0, 0xF0, 0xFF, 0x0F, + 0x0F, 0xF0, 0xF0, 0xFF, 0x0F, 0x0F, 0xE0, 0x3F, 0x80, 0xFF, 0x03, 0xFC, + 0x0F, 0xF8, 0x3F, 0xE0, 0xFF, 0x83, 0xFF, 0x0F, 0xFC, 0x3F, 0xF0, 0xFF, + 0xE3, 0xFF, 0x8F, 0xFE, 0x3F, 0xFC, 0xFF, 0xF3, 0xFD, 0xCF, 0xF7, 0xBF, + 0xDE, 0xFF, 0x3B, 0xFC, 0xFF, 0xF3, 0xDF, 0xC7, 0x7F, 0x1F, 0xFC, 0x7F, + 0xF0, 0xFF, 0xC3, 0xFF, 0x0F, 0xFC, 0x1F, 0xF0, 0x7F, 0xC1, 0xFF, 0x03, + 0xFC, 0x0F, 0xF0, 0x3F, 0xC0, 0x70, 0x0F, 0xE0, 0x7F, 0xC3, 0xFF, 0x9F, + 0xFE, 0x7C, 0x7D, 0xE1, 0xFF, 0x83, 0xFE, 0x0F, 0xF8, 0x3F, 0xE0, 0xFF, + 0x83, 0xFE, 0x0F, 0xF8, 0x3F, 0xE0, 0xFF, 0x83, 0xFE, 0x0F, 0xF8, 0x3F, + 0xE0, 0xFF, 0x83, 0xFE, 0x0F, 0xF8, 0x3F, 0xE0, 0xFF, 0x83, 0xFE, 0x0F, + 0xF8, 0x3F, 0xE0, 0xFF, 0x83, 0xFE, 0x0F, 0x78, 0x7D, 0xE1, 0xF7, 0xFF, + 0x8F, 0xFE, 0x3F, 0xF0, 0x3F, 0x80, 0xFF, 0x87, 0xFF, 0x3F, 0xFD, 0xFF, + 0xEF, 0x0F, 0xF8, 0x3F, 0xC1, 0xFE, 0x0F, 0xF0, 0x7F, 0x83, 0xFC, 0x1F, + 0xE0, 0xFF, 0x07, 0xF8, 0x3F, 0xC1, 0xFE, 0x1F, 0xF0, 0xFF, 0xFF, 0xBF, + 0xFD, 0xFF, 0xCF, 0xF8, 0x78, 0x03, 0xC0, 0x1E, 0x00, 0xF0, 0x07, 0x80, + 0x3C, 0x01, 0xE0, 0x0F, 0x00, 0x78, 0x03, 0xC0, 0x1E, 0x00, 0xF0, 0x07, + 0x80, 0x00, 0x0F, 0xE0, 0x7F, 0xC3, 0xFF, 0x9F, 0xFE, 0x7C, 0x7D, 0xE1, + 0xFF, 0x83, 0xFE, 0x0F, 0xF8, 0x3F, 0xE0, 0xFF, 0x83, 0xFE, 0x0F, 0xF8, + 0x3F, 0xE0, 0xFF, 0x83, 0xFE, 0x0F, 0xF8, 0x3F, 0xE0, 0xFF, 0x83, 0xFE, + 0x0F, 0xF8, 0x3F, 0xE0, 0xFF, 0x83, 0xFE, 0x0F, 0xF8, 0x3F, 0xE0, 0xFF, + 0x83, 0xFE, 0x0F, 0x78, 0x7D, 0xE1, 0xF7, 0xFF, 0x8F, 0xFE, 0x3F, 0xF0, + 0x3F, 0x80, 0x1E, 0x00, 0x3C, 0x00, 0x78, 0x01, 0xE0, 0x03, 0x00, 0xFF, + 0x83, 0xFF, 0x8F, 0xFF, 0x3F, 0xFE, 0xF0, 0xFB, 0xC1, 0xEF, 0x07, 0xBC, + 0x1E, 0xF0, 0x7B, 0xC1, 0xEF, 0x07, 0xBC, 0x1E, 0xF0, 0x7B, 0xC3, 0xEF, + 0x1F, 0x3F, 0xFC, 0xFF, 0xE3, 0xFF, 0xCF, 0x0F, 0xBC, 0x1E, 0xF0, 0x7B, + 0xC1, 0xEF, 0x07, 0xBC, 0x1E, 0xF0, 0x7B, 0xC1, 0xEF, 0x07, 0xBC, 0x1E, + 0xF0, 0x7B, 0xC1, 0xEF, 0x07, 0xBC, 0x1E, 0xF0, 0x7B, 0xC1, 0xF0, 0x0F, + 0xC0, 0xFF, 0xC3, 0xFF, 0x1F, 0xFE, 0x78, 0x79, 0xE1, 0xEF, 0x87, 0xBE, + 0x1F, 0xF8, 0x7D, 0xE1, 0xF7, 0x87, 0xDF, 0x1F, 0x7E, 0x00, 0xFC, 0x01, + 0xF8, 0x03, 0xF0, 0x0F, 0xE0, 0x1F, 0x80, 0x3F, 0x00, 0x7E, 0x00, 0xF9, + 0xE1, 0xF7, 0x87, 0xDE, 0x0F, 0x78, 0x3D, 0xE0, 0xF7, 0x83, 0xDE, 0x0F, + 0x78, 0x3D, 0xE1, 0xF7, 0xEF, 0x8F, 0xFE, 0x3F, 0xF0, 0x3F, 0x80, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0F, 0x80, 0xF8, 0x0F, 0x80, 0xF8, 0x0F, + 0x80, 0xF8, 0x0F, 0x80, 0xF8, 0x0F, 0x80, 0xF8, 0x0F, 0x80, 0xF8, 0x0F, + 0x80, 0xF8, 0x0F, 0x80, 0xF8, 0x0F, 0x80, 0xF8, 0x0F, 0x80, 0xF8, 0x0F, + 0x80, 0xF8, 0x0F, 0x80, 0xF8, 0x0F, 0x80, 0xF8, 0x0F, 0x80, 0xF8, 0x0F, + 0x80, 0xF8, 0xF8, 0x3F, 0xE0, 0xFF, 0x83, 0xFE, 0x0F, 0xF8, 0x3F, 0xE0, + 0xFF, 0x83, 0xFE, 0x0F, 0xF8, 0x3F, 0xE0, 0xFF, 0x83, 0xFE, 0x0F, 0xF8, + 0x3F, 0xE0, 0xFF, 0x83, 0xFE, 0x0F, 0xF8, 0x3F, 0xE0, 0xFF, 0x83, 0xFE, + 0x0F, 0xF8, 0x3F, 0xE0, 0xFF, 0x83, 0xFE, 0x0F, 0xF8, 0x3F, 0xE0, 0xFF, + 0x83, 0xFE, 0x0F, 0x78, 0x3D, 0xE1, 0xF7, 0xEF, 0xCF, 0xFE, 0x3F, 0xF8, + 0x7F, 0x80, 0xF0, 0x1F, 0xF0, 0x1E, 0xF0, 0x1E, 0xF0, 0x1E, 0xF8, 0x1E, + 0x78, 0x1E, 0x78, 0x1E, 0x78, 0x3C, 0x78, 0x3C, 0x78, 0x3C, 0x7C, 0x3C, + 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x78, 0x3C, 0x78, 0x3C, 0x78, + 0x1E, 0x78, 0x1E, 0x78, 0x1E, 0x78, 0x1E, 0x78, 0x1E, 0x70, 0x1E, 0xF0, + 0x0E, 0xF0, 0x0F, 0xF0, 0x0F, 0xF0, 0x0F, 0xF0, 0x0F, 0xF0, 0x0F, 0xE0, + 0x0F, 0xE0, 0x07, 0xE0, 0x07, 0xE0, 0x07, 0xE0, 0x07, 0xE0, 0xF0, 0x3C, + 0x0F, 0xF0, 0x3C, 0x0F, 0xF0, 0x3C, 0x0F, 0xF0, 0x3C, 0x1E, 0xF0, 0x3C, + 0x1E, 0x78, 0x3E, 0x1E, 0x78, 0x7E, 0x1E, 0x78, 0x7E, 0x1E, 0x78, 0x7E, + 0x1E, 0x78, 0x7E, 0x1E, 0x78, 0x7E, 0x1E, 0x78, 0x7E, 0x1E, 0x38, 0x7F, + 0x1C, 0x38, 0xF7, 0x1C, 0x3C, 0xF7, 0x3C, 0x3C, 0xE7, 0x3C, 0x3C, 0xE7, + 0x3C, 0x3C, 0xE7, 0x3C, 0x3C, 0xE7, 0x3C, 0x3C, 0xE7, 0xBC, 0x1D, 0xE3, + 0xB8, 0x1D, 0xC3, 0xB8, 0x1D, 0xC3, 0xB8, 0x1F, 0xC3, 0xB8, 0x1F, 0xC3, + 0xB8, 0x1F, 0xC3, 0xF8, 0x1F, 0xC3, 0xF8, 0x1F, 0xC1, 0xF8, 0x0F, 0x81, + 0xF8, 0x0F, 0x81, 0xF0, 0x0F, 0x81, 0xF0, 0x0F, 0x81, 0xF0, 0x0F, 0x81, + 0xF0, 0x0F, 0x81, 0xF0, 0xF0, 0x3F, 0xC0, 0xF7, 0x07, 0x9E, 0x1E, 0x78, + 0x78, 0xE3, 0xE3, 0xCF, 0x0F, 0x3C, 0x3C, 0xF0, 0x7F, 0x81, 0xFE, 0x07, + 0xF8, 0x0F, 0xE0, 0x3F, 0x00, 0xFC, 0x01, 0xF0, 0x07, 0x80, 0x3E, 0x00, + 0xF8, 0x03, 0xF0, 0x0F, 0xC0, 0x7F, 0x01, 0xFE, 0x07, 0xF8, 0x3F, 0xE0, + 0xF3, 0xC3, 0xCF, 0x0F, 0x3C, 0x78, 0x71, 0xE1, 0xE7, 0x87, 0x9E, 0x0E, + 0xF0, 0x3F, 0xC0, 0xF0, 0xF8, 0x0F, 0x78, 0x1F, 0x78, 0x1E, 0x7C, 0x1E, + 0x3C, 0x1E, 0x3C, 0x3E, 0x3C, 0x3C, 0x3E, 0x3C, 0x1E, 0x3C, 0x1E, 0x78, + 0x1E, 0x78, 0x0F, 0x78, 0x0F, 0x78, 0x0F, 0xF0, 0x0F, 0xF0, 0x07, 0xF0, + 0x07, 0xF0, 0x07, 0xE0, 0x03, 0xE0, 0x03, 0xE0, 0x03, 0xE0, 0x03, 0xE0, + 0x03, 0xE0, 0x03, 0xE0, 0x03, 0xE0, 0x03, 0xE0, 0x03, 0xE0, 0x03, 0xE0, + 0x03, 0xE0, 0x03, 0xE0, 0x03, 0xE0, 0x03, 0xE0, 0x03, 0xE0, 0x03, 0xE0, + 0x7F, 0xF7, 0xFF, 0x7F, 0xF7, 0xFF, 0x01, 0xF0, 0x1E, 0x01, 0xE0, 0x3E, + 0x03, 0xE0, 0x3C, 0x07, 0xC0, 0x7C, 0x07, 0xC0, 0x78, 0x0F, 0x80, 0xF8, + 0x0F, 0x80, 0xF0, 0x1F, 0x01, 0xF0, 0x1E, 0x01, 0xE0, 0x3E, 0x03, 0xE0, + 0x3C, 0x07, 0xC0, 0x7C, 0x07, 0xC0, 0x78, 0x0F, 0x80, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, + 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, + 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xFF, + 0xFF, 0xFF, 0xF0, 0x1E, 0x03, 0xC0, 0x78, 0x07, 0x00, 0xF0, 0x1E, 0x03, + 0xC0, 0x78, 0x07, 0x80, 0xF0, 0x1E, 0x03, 0xC0, 0x3C, 0x07, 0x80, 0xF0, + 0x1E, 0x01, 0xC0, 0x3C, 0x07, 0x80, 0xF0, 0x0E, 0x01, 0xE0, 0x3C, 0x07, + 0x80, 0xF0, 0x0F, 0x01, 0xE0, 0x3C, 0x07, 0x80, 0x78, 0x0F, 0x01, 0xE0, + 0x3C, 0xFF, 0xFF, 0xFF, 0xFF, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, + 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, + 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0xFF, 0xFF, 0xFF, + 0x0F, 0xC0, 0x1F, 0x80, 0x3F, 0x80, 0x7F, 0x01, 0xFE, 0x03, 0xDC, 0x07, + 0xBC, 0x0E, 0x78, 0x3C, 0xF0, 0x79, 0xE0, 0xF1, 0xE1, 0xE3, 0xC7, 0x87, + 0x8F, 0x0F, 0x1E, 0x0F, 0x3C, 0x1E, 0xF8, 0x3D, 0xE0, 0x7C, 0xFF, 0xFF, + 0xFF, 0xFF, 0xF0, 0xF9, 0xE7, 0x8E, 0x38, 0x71, 0xC3, 0x0F, 0xC0, 0xFF, + 0xC3, 0xFF, 0x1F, 0xFE, 0x78, 0x79, 0xE1, 0xEF, 0x87, 0xBE, 0x1E, 0xF8, + 0x7C, 0x01, 0xF0, 0x07, 0xC0, 0x7F, 0x0F, 0xFC, 0x7F, 0xF3, 0xE7, 0xDE, + 0x1F, 0xF8, 0x7F, 0xE1, 0xFF, 0x87, 0xFE, 0x1F, 0xF8, 0x7F, 0xE1, 0xFF, + 0x87, 0xFE, 0x1F, 0xF8, 0x7D, 0xE3, 0xF7, 0xFF, 0xDF, 0xFF, 0x3F, 0x7C, + 0xF0, 0x07, 0x80, 0x3C, 0x01, 0xE0, 0x0F, 0x00, 0x79, 0xE3, 0xDF, 0x9F, + 0xFE, 0xFF, 0xFF, 0xC7, 0xFC, 0x1F, 0xE0, 0xFF, 0x07, 0xF8, 0x3F, 0xC1, + 0xFE, 0x0F, 0xF0, 0x7F, 0x83, 0xFC, 0x1F, 0xE0, 0xFF, 0x07, 0xF8, 0x3F, + 0xC1, 0xFE, 0x0F, 0xF0, 0x7F, 0x83, 0xFC, 0x1F, 0xE0, 0xFF, 0x07, 0xFC, + 0x7F, 0xF7, 0xFF, 0xFE, 0xF7, 0xF7, 0x9F, 0x00, 0x0F, 0xC1, 0xFF, 0x8F, + 0xFC, 0xFF, 0xF7, 0x87, 0xBC, 0x3F, 0xE1, 0xFF, 0x0F, 0xF8, 0x7F, 0xC3, + 0xFE, 0x1F, 0xF0, 0x0F, 0x80, 0x7C, 0x03, 0xE0, 0x1F, 0x00, 0xF8, 0x07, + 0xC0, 0x3E, 0x1F, 0xF0, 0xFF, 0x87, 0xFC, 0x3F, 0xE1, 0xEF, 0x0F, 0x78, + 0x7B, 0xE7, 0xDF, 0xFC, 0x7F, 0xE1, 0xFE, 0x00, 0x00, 0x7C, 0x01, 0xF0, + 0x07, 0xC0, 0x1F, 0x00, 0x7C, 0x7D, 0xF3, 0xFF, 0xDF, 0xFF, 0x7F, 0xFD, + 0xE1, 0xFF, 0x87, 0xFE, 0x1F, 0xF8, 0x7F, 0xE1, 0xFF, 0x87, 0xFE, 0x1F, + 0xF8, 0x7F, 0xE1, 0xFF, 0x87, 0xFE, 0x1F, 0xF8, 0x7F, 0xE1, 0xFF, 0x87, + 0xFE, 0x1F, 0xF8, 0x7F, 0xE1, 0xFF, 0x87, 0xFE, 0x1F, 0xF8, 0x7D, 0xE1, + 0xF7, 0xDF, 0xDF, 0xFF, 0x3F, 0xFC, 0x7D, 0xF0, 0x0F, 0xC0, 0x7F, 0xC3, + 0xFF, 0x1F, 0xFE, 0x78, 0x79, 0xE1, 0xEF, 0x87, 0xBE, 0x1E, 0xF8, 0x7B, + 0xE1, 0xFF, 0x87, 0xFE, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x00, + 0xF8, 0x03, 0xE0, 0x0F, 0x87, 0xBE, 0x1E, 0xF8, 0x7B, 0xE1, 0xEF, 0x87, + 0x9E, 0x1E, 0x78, 0x79, 0xF3, 0xE7, 0xFF, 0x0F, 0xFC, 0x1F, 0xE0, 0x07, + 0xC3, 0xF1, 0xFC, 0x7C, 0x1E, 0x07, 0x8F, 0xFF, 0xFF, 0xFF, 0xFF, 0xF1, + 0xE0, 0x78, 0x1E, 0x07, 0x81, 0xE0, 0x78, 0x1E, 0x07, 0x81, 0xE0, 0x78, + 0x1E, 0x07, 0x81, 0xE0, 0x78, 0x1E, 0x07, 0x81, 0xE0, 0x78, 0x1E, 0x07, + 0x81, 0xE0, 0x78, 0x1E, 0x07, 0x80, 0x1F, 0x7C, 0xFF, 0xF7, 0xFF, 0xDF, + 0xFF, 0x78, 0x7D, 0xE1, 0xFF, 0x87, 0xFE, 0x1F, 0xF8, 0x7F, 0xE1, 0xFF, + 0x87, 0xFE, 0x1F, 0xF8, 0x7F, 0xE1, 0xFF, 0x87, 0xFE, 0x1F, 0xF8, 0x7F, + 0xE1, 0xFF, 0x87, 0xFE, 0x1F, 0xF8, 0x7D, 0xE1, 0xF7, 0xCF, 0xDF, 0xFF, + 0x3F, 0xFC, 0x7D, 0xF0, 0x07, 0xC0, 0x1F, 0x00, 0x79, 0xC3, 0xE7, 0xFF, + 0xBF, 0xFC, 0x3F, 0xC0, 0xF0, 0x07, 0x80, 0x3C, 0x01, 0xE0, 0x0F, 0x00, + 0x79, 0xF3, 0xDF, 0xDF, 0xFF, 0xFF, 0xFF, 0xC3, 0xFC, 0x1F, 0xE0, 0xFF, + 0x07, 0xF8, 0x3F, 0xC1, 0xFE, 0x0F, 0xF0, 0x7F, 0x83, 0xFC, 0x1F, 0xE0, + 0xFF, 0x07, 0xF8, 0x3F, 0xC1, 0xFE, 0x0F, 0xF0, 0x7F, 0x83, 0xFC, 0x1F, + 0xE0, 0xFF, 0x07, 0xF8, 0x3F, 0xC1, 0xFE, 0x0F, 0xF0, 0x7F, 0x83, 0xC0, + 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x3C, 0x78, 0xF1, 0xE0, 0x00, 0x0F, + 0x9F, 0x3E, 0x7C, 0xF9, 0xF3, 0xE7, 0xCF, 0x9F, 0x3E, 0x7C, 0xF9, 0xF3, + 0xE7, 0xCF, 0x9F, 0x3E, 0x7C, 0xF9, 0xF3, 0xE7, 0xCF, 0x9F, 0x3E, 0x7C, + 0xF9, 0xFF, 0xDF, 0xBE, 0x00, 0xF0, 0x03, 0xC0, 0x0F, 0x00, 0x3C, 0x00, + 0xF0, 0x03, 0xC1, 0xFF, 0x07, 0xBC, 0x1E, 0xF0, 0xFB, 0xC3, 0xCF, 0x1F, + 0x3C, 0x78, 0xF1, 0xE3, 0xCF, 0x8F, 0x3C, 0x3D, 0xF0, 0xF7, 0x83, 0xDE, + 0x0F, 0xF8, 0x3F, 0xC0, 0xFF, 0x83, 0xDE, 0x0F, 0x78, 0x3D, 0xF0, 0xF3, + 0xC3, 0xCF, 0x8F, 0x1E, 0x3C, 0x7C, 0xF0, 0xF3, 0xC3, 0xCF, 0x0F, 0xBC, + 0x1E, 0xF0, 0x7F, 0xC0, 0xF0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF3, 0xE1, + 0xF3, 0xDF, 0xCF, 0xEF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0xFC, 0x3F, + 0xC1, 0xE0, 0xFF, 0x07, 0x83, 0xFC, 0x1E, 0x0F, 0xF0, 0x78, 0x3F, 0xC1, + 0xE0, 0xFF, 0x07, 0x83, 0xFC, 0x1E, 0x0F, 0xF0, 0x78, 0x3F, 0xC1, 0xE0, + 0xFF, 0x07, 0x83, 0xFC, 0x1E, 0x0F, 0xF0, 0x78, 0x3F, 0xC1, 0xE0, 0xFF, + 0x07, 0x83, 0xFC, 0x1E, 0x0F, 0xF0, 0x78, 0x3F, 0xC1, 0xE0, 0xFF, 0x07, + 0x83, 0xFC, 0x1E, 0x0F, 0xF0, 0x78, 0x3F, 0xC1, 0xE0, 0xFF, 0x07, 0x83, + 0xFC, 0x1E, 0x0F, 0xF0, 0x78, 0x3C, 0xF3, 0xE7, 0xBF, 0xBF, 0xFF, 0xFF, + 0xFF, 0x87, 0xF8, 0x3F, 0xC1, 0xFE, 0x0F, 0xF0, 0x7F, 0x83, 0xFC, 0x1F, + 0xE0, 0xFF, 0x07, 0xF8, 0x3F, 0xC1, 0xFE, 0x0F, 0xF0, 0x7F, 0x83, 0xFC, + 0x1F, 0xE0, 0xFF, 0x07, 0xF8, 0x3F, 0xC1, 0xFE, 0x0F, 0xF0, 0x7F, 0x83, + 0xFC, 0x1F, 0xE0, 0xFF, 0x07, 0x80, 0x0F, 0xC0, 0x7F, 0x83, 0xFF, 0x1F, + 0xFE, 0x78, 0x79, 0xE1, 0xEF, 0x87, 0xBE, 0x1F, 0xF8, 0x7F, 0xE1, 0xFF, + 0x87, 0xFE, 0x1F, 0xF8, 0x7F, 0xE1, 0xFF, 0x87, 0xFE, 0x1F, 0xF8, 0x7F, + 0xE1, 0xFF, 0x87, 0xFE, 0x1F, 0xF8, 0x7F, 0xE1, 0xFF, 0x87, 0xDE, 0x1E, + 0x78, 0x79, 0xF3, 0xE7, 0xFF, 0x0F, 0xFC, 0x1F, 0xE0, 0xF3, 0xC7, 0xBF, + 0xBF, 0xFD, 0xFF, 0xFF, 0x8F, 0xF8, 0x7F, 0xC1, 0xFE, 0x0F, 0xF0, 0x7F, + 0x83, 0xFC, 0x1F, 0xE0, 0xFF, 0x07, 0xF8, 0x3F, 0xC1, 0xFE, 0x0F, 0xF0, + 0x7F, 0x83, 0xFC, 0x1F, 0xE0, 0xFF, 0x07, 0xF8, 0x3F, 0xC1, 0xFE, 0x0F, + 0xF8, 0xFF, 0xEF, 0xFF, 0xFD, 0xFF, 0xEF, 0x7E, 0x78, 0x03, 0xC0, 0x1E, + 0x00, 0xF0, 0x07, 0x80, 0x00, 0x1E, 0x7C, 0xFF, 0xF7, 0xFF, 0xDF, 0xFF, + 0x78, 0x7F, 0xE1, 0xFF, 0x87, 0xFE, 0x1F, 0xF8, 0x7F, 0xE1, 0xFF, 0x87, + 0xFE, 0x1F, 0xF8, 0x7F, 0xE1, 0xFF, 0x87, 0xFE, 0x1F, 0xF8, 0x7F, 0xE1, + 0xFF, 0x87, 0xFE, 0x1F, 0xF8, 0x7F, 0xE1, 0xFF, 0x87, 0xFE, 0x1F, 0x78, + 0x7D, 0xF7, 0xF7, 0xFF, 0xCF, 0xFF, 0x1F, 0x7C, 0x01, 0xF0, 0x07, 0xC0, + 0x1F, 0x00, 0x7C, 0x01, 0xF0, 0xF3, 0xFB, 0xFF, 0xFF, 0xFF, 0xC7, 0x83, + 0xC1, 0xE0, 0xF0, 0x78, 0x3C, 0x1E, 0x0F, 0x07, 0x83, 0xC1, 0xE0, 0xF0, + 0x78, 0x3C, 0x1E, 0x0F, 0x07, 0x83, 0xC1, 0xE0, 0xF0, 0x78, 0x3C, 0x1E, + 0x0F, 0x00, 0x1F, 0x83, 0xFE, 0x1F, 0xF9, 0xFF, 0xCF, 0x0F, 0x78, 0x7B, + 0xC3, 0xDE, 0x1E, 0xF0, 0xF7, 0xC7, 0xBE, 0x00, 0xF8, 0x07, 0xE0, 0x1F, + 0x80, 0x7E, 0x01, 0xF8, 0x07, 0xE0, 0x1F, 0x80, 0x7D, 0xE1, 0xEF, 0x0F, + 0xF8, 0x7F, 0xC3, 0xFE, 0x1F, 0xF0, 0xF7, 0xEF, 0x9F, 0xFC, 0xFF, 0xC1, + 0xFC, 0x00, 0x3E, 0x0F, 0x83, 0xE0, 0xF8, 0x3E, 0x0F, 0x8F, 0xFF, 0xFF, + 0xFF, 0xCF, 0x83, 0xE0, 0xF8, 0x3E, 0x0F, 0x83, 0xE0, 0xF8, 0x3E, 0x0F, + 0x83, 0xE0, 0xF8, 0x3E, 0x0F, 0x83, 0xE0, 0xF8, 0x3E, 0x0F, 0x83, 0xE0, + 0xF8, 0x3E, 0x0F, 0x83, 0xF0, 0xFF, 0x1F, 0xC3, 0xF0, 0xF8, 0x3F, 0xE0, + 0xFF, 0x83, 0xFE, 0x0F, 0xF8, 0x3F, 0xE0, 0xFF, 0x83, 0xFE, 0x0F, 0xF8, + 0x3F, 0xE0, 0xFF, 0x83, 0xFE, 0x0F, 0xF8, 0x3F, 0xE0, 0xFF, 0x83, 0xFE, + 0x0F, 0xF8, 0x3F, 0xE0, 0xFF, 0x83, 0xFE, 0x0F, 0xF8, 0x3F, 0xE0, 0xFF, + 0x83, 0xFE, 0x0F, 0x78, 0x7D, 0xF3, 0xF7, 0xFF, 0xCF, 0xEF, 0x1F, 0x3C, + 0xF0, 0x7F, 0xC1, 0xEF, 0x07, 0xBC, 0x1E, 0x78, 0x79, 0xE1, 0xE7, 0x87, + 0x9E, 0x1C, 0x78, 0x71, 0xE3, 0xC7, 0x8F, 0x0E, 0x3C, 0x3C, 0xF0, 0xF3, + 0xC3, 0xCE, 0x0F, 0x38, 0x3C, 0xE0, 0xF3, 0x81, 0xDE, 0x07, 0x78, 0x1F, + 0xE0, 0x7F, 0x01, 0xFC, 0x07, 0xF0, 0x1F, 0xC0, 0x3F, 0x00, 0xFC, 0x03, + 0xF0, 0x0F, 0x80, 0xF0, 0x78, 0x7F, 0x87, 0xC3, 0xFC, 0x3E, 0x1F, 0xE1, + 0xF0, 0xF7, 0x0F, 0x87, 0xB8, 0x7C, 0x39, 0xC3, 0xE1, 0xCE, 0x1F, 0x8E, + 0x79, 0xDC, 0x73, 0xCE, 0xE7, 0x9E, 0x77, 0x3C, 0xF3, 0xB9, 0xE3, 0x9D, + 0xCF, 0x1C, 0xE6, 0x70, 0xE7, 0x3B, 0x87, 0x71, 0xDC, 0x3B, 0x8E, 0xE1, + 0xDC, 0x77, 0x0F, 0xE3, 0xB8, 0x7F, 0x1D, 0xC3, 0xF8, 0xFE, 0x0F, 0x83, + 0xE0, 0x7C, 0x1F, 0x03, 0xE0, 0xF8, 0x1F, 0x07, 0xC0, 0xF8, 0x3E, 0x07, + 0xC1, 0xF0, 0x3E, 0x0F, 0x81, 0xE0, 0x7C, 0x00, 0xF0, 0x7B, 0xC1, 0xE7, + 0x87, 0x9E, 0x3C, 0x78, 0xF0, 0xF3, 0xC3, 0xCE, 0x0F, 0x78, 0x1F, 0xE0, + 0x7F, 0x01, 0xFC, 0x03, 0xF0, 0x0F, 0x80, 0x3E, 0x00, 0xF8, 0x03, 0xE0, + 0x0F, 0x80, 0x7F, 0x01, 0xFC, 0x07, 0xF0, 0x3D, 0xE0, 0xF7, 0x83, 0xDE, + 0x1E, 0x3C, 0x78, 0xF1, 0xE3, 0xCF, 0x07, 0xBC, 0x1E, 0xF0, 0x7C, 0xF0, + 0x3F, 0xC0, 0xFF, 0x07, 0xFE, 0x1E, 0x78, 0x79, 0xE1, 0xE7, 0x87, 0x9E, + 0x1E, 0x78, 0x79, 0xE1, 0xC3, 0x87, 0x0F, 0x3C, 0x3C, 0xF0, 0xF3, 0xC3, + 0xCF, 0x0F, 0x3C, 0x1C, 0xE0, 0x73, 0x81, 0xCE, 0x07, 0xB8, 0x1F, 0xE0, + 0x7F, 0x80, 0xFC, 0x03, 0xF0, 0x0F, 0xC0, 0x3F, 0x00, 0xFC, 0x03, 0xF0, + 0x07, 0x80, 0x1E, 0x00, 0xF8, 0x1F, 0xE0, 0x7F, 0x01, 0xFC, 0x00, 0x7F, + 0xEF, 0xFD, 0xFF, 0xBF, 0xF0, 0x1E, 0x07, 0xC0, 0xF0, 0x1E, 0x07, 0xC0, + 0xF0, 0x1E, 0x03, 0xC0, 0xF8, 0x1E, 0x03, 0xC0, 0xF8, 0x1E, 0x03, 0xC0, + 0xF8, 0x1F, 0x03, 0xC0, 0x78, 0x1F, 0x03, 0xC0, 0x78, 0x1F, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFE, 0x07, 0xC3, 0xF1, 0xFC, 0x7E, 0x1E, 0x07, 0x81, 0xE0, + 0x78, 0x1E, 0x07, 0x81, 0xE0, 0x78, 0x1E, 0x07, 0x81, 0xE0, 0xF8, 0x7E, + 0x3F, 0x0F, 0x83, 0xF0, 0xFE, 0x0F, 0x81, 0xE0, 0x78, 0x1E, 0x07, 0x81, + 0xE0, 0x78, 0x1E, 0x07, 0x81, 0xE0, 0x78, 0x1E, 0x07, 0xC1, 0xFC, 0x3F, + 0x07, 0xC0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0xF8, 0x3F, 0x0F, + 0xC1, 0xF8, 0x3E, 0x07, 0x81, 0xE0, 0x78, 0x1E, 0x07, 0x81, 0xE0, 0x78, + 0x1E, 0x07, 0x81, 0xE0, 0x78, 0x1F, 0x83, 0xF0, 0x7C, 0x3F, 0x1F, 0xC7, + 0x81, 0xE0, 0x78, 0x1E, 0x07, 0x81, 0xE0, 0x78, 0x1E, 0x07, 0x81, 0xE0, + 0x78, 0x3E, 0x0F, 0x8F, 0xC3, 0xF0, 0xF8, 0x00, 0x1E, 0x07, 0x9F, 0xF3, + 0xDF, 0xFF, 0xDF, 0xFF, 0xEF, 0xFF, 0xE1, 0x03, 0xE0}; const GFXglyph Antonio_SemiBold20pt7bGlyphs[] PROGMEM = { {0, 1, 1, 8, 0, 0}, // 0x20 ' ' @@ -284,13 +477,8 @@ const GFXglyph Antonio_SemiBold20pt7bGlyphs[] PROGMEM = { {4461, 10, 37, 14, 2, -33}, // 0x7D '}' {4508, 17, 6, 21, 2, -21}}; // 0x7E '~' -// Font properties -static constexpr FontData Antonio_SemiBold20pt7b_Properties = { - Antonio_SemiBold20pt7bBitmaps_Gzip, - Antonio_SemiBold20pt7bGlyphs, - sizeof(Antonio_SemiBold20pt7bBitmaps_Gzip), - 4521, // Original size - 0x20, // First char - 0x7E, // Last char - 51 // yAdvance -}; +const GFXfont Antonio_SemiBold20pt7b PROGMEM = { + (uint8_t *)Antonio_SemiBold20pt7bBitmaps, + (GFXglyph *)Antonio_SemiBold20pt7bGlyphs, 0x20, 0x7E, 51}; + +// Approx. 5193 bytes diff --git a/src/fonts/antonio-semibold40.h b/src/fonts/antonio-semibold40.h index 3790765..0f8ea5f 100644 --- a/src/fonts/antonio-semibold40.h +++ b/src/fonts/antonio-semibold40.h @@ -1,488 +1,1532 @@ -#pragma once - #include #include -const uint8_t Antonio_SemiBold40pt7bBitmaps_Gzip[] = { - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xe5, 0x5c, - 0xbd, 0x72, 0xec, 0x3a, 0x72, 0x06, 0x8b, 0x5b, 0x66, 0xb2, 0x65, 0xdc, - 0xd0, 0x81, 0x77, 0xf1, 0x0a, 0x1b, 0x3a, 0xb8, 0x75, 0xe0, 0x47, 0x72, - 0xe8, 0xe0, 0x78, 0x40, 0x95, 0x02, 0x85, 0xf3, 0x08, 0x7a, 0x93, 0x15, - 0x55, 0x0a, 0x14, 0xce, 0x23, 0x0c, 0x65, 0x05, 0x0a, 0x05, 0x95, 0x02, - 0x41, 0x25, 0x0a, 0xed, 0xef, 0x6b, 0x90, 0x1c, 0xce, 0x48, 0x3a, 0xd2, - 0xf9, 0xdd, 0x5b, 0xde, 0x39, 0x73, 0x40, 0x70, 0x48, 0x82, 0x0d, 0xa0, - 0x7f, 0xbe, 0xee, 0x06, 0x64, 0x64, 0xfc, 0x3c, 0xe6, 0x70, 0x7a, 0x73, - 0x50, 0xa4, 0xc1, 0xdb, 0x8b, 0x78, 0x58, 0xfc, 0xb5, 0x39, 0xea, 0xff, - 0x7b, 0x2e, 0xcc, 0xf8, 0xb1, 0x4f, 0x59, 0xce, 0x6e, 0xb5, 0x48, 0x22, - 0xb7, 0xd3, 0x99, 0xbb, 0xbc, 0x1b, 0x02, 0x8a, 0xb4, 0x72, 0x27, 0x57, - 0x2c, 0xce, 0xe3, 0x67, 0x63, 0x9a, 0xde, 0xb7, 0x55, 0xb2, 0x9d, 0xc9, - 0x75, 0x34, 0xfe, 0x68, 0x30, 0xb6, 0x0f, 0xa6, 0x8e, 0xae, 0x33, 0x43, - 0x83, 0x1f, 0xaa, 0x64, 0x5c, 0xb7, 0x32, 0x4d, 0xc4, 0x5d, 0x83, 0xed, - 0xcd, 0xaa, 0xc6, 0x0f, 0x6d, 0xe6, 0x63, 0xa6, 0xd6, 0xc7, 0x9a, 0xf1, - 0xb1, 0x6e, 0x7e, 0xac, 0x37, 0x41, 0x1f, 0xcb, 0x35, 0x3a, 0x33, 0xb0, - 0x47, 0x1e, 0xff, 0x37, 0xf8, 0x7f, 0xcf, 0x1f, 0xea, 0xe4, 0xc6, 0xc7, - 0xaa, 0xf9, 0x31, 0x34, 0xbe, 0x7b, 0x6c, 0xa2, 0x89, 0x6f, 0xc3, 0x5d, - 0xed, 0xf0, 0x7a, 0x3b, 0xcd, 0xfc, 0xd8, 0x8e, 0xa6, 0x45, 0x57, 0xda, - 0xb1, 0x2b, 0x69, 0xee, 0xca, 0x30, 0x76, 0xc5, 0x95, 0xae, 0xbc, 0xfe, - 0xd8, 0x72, 0x04, 0x8c, 0xc3, 0xf8, 0x74, 0xa6, 0x8a, 0xc6, 0x7c, 0x7e, - 0x79, 0x12, 0x92, 0x09, 0xd2, 0x7a, 0x89, 0x4e, 0x06, 0x2b, 0x72, 0x2c, - 0x72, 0x07, 0xaa, 0xc2, 0xb9, 0xb8, 0xe8, 0x6f, 0x13, 0x26, 0xa1, 0xca, - 0xd2, 0x86, 0xb3, 0xde, 0xdd, 0xa6, 0x66, 0x3c, 0x39, 0xed, 0xdd, 0xcd, - 0xd0, 0x3c, 0x4a, 0x95, 0x43, 0x1f, 0xd6, 0x83, 0xa9, 0x05, 0xcd, 0xf4, - 0xc6, 0x65, 0xd4, 0x3a, 0x36, 0xe8, 0x04, 0x35, 0x90, 0x06, 0x22, 0xa4, - 0x35, 0x12, 0x8d, 0xe3, 0x4d, 0xad, 0x09, 0xd1, 0xd8, 0xc1, 0x54, 0xac, - 0xdd, 0x24, 0xfb, 0x88, 0x91, 0x0d, 0x6d, 0xd8, 0xf6, 0xee, 0x21, 0x35, - 0xcf, 0xb9, 0xc2, 0x89, 0xdf, 0xf6, 0xf6, 0x21, 0xd5, 0x7a, 0xd2, 0x85, - 0x6d, 0x74, 0x0f, 0xd9, 0x0e, 0x72, 0x99, 0x31, 0x62, 0x27, 0x22, 0x57, - 0x22, 0xd1, 0x4b, 0x6a, 0x64, 0x30, 0x82, 0x0e, 0x0f, 0xc6, 0xfc, 0x0e, - 0x36, 0x31, 0xa6, 0x46, 0x1f, 0xe3, 0x8b, 0x13, 0xbe, 0x46, 0x3f, 0x0d, - 0x48, 0x31, 0x4d, 0x42, 0x6f, 0x05, 0x05, 0xc6, 0xd0, 0x78, 0xb4, 0xb0, - 0xab, 0x60, 0x10, 0x31, 0x04, 0x79, 0xac, 0x3c, 0x4c, 0x95, 0x23, 0xf4, - 0x8a, 0xa3, 0x27, 0x66, 0x59, 0xf1, 0xed, 0x5e, 0x25, 0x2c, 0x2a, 0xf8, - 0x1e, 0x54, 0xf2, 0x9b, 0x15, 0xcc, 0xe2, 0x41, 0xa5, 0x9e, 0x2b, 0xe9, - 0xb0, 0x42, 0x4a, 0xc7, 0x0a, 0x46, 0x91, 0x15, 0x1b, 0xad, 0xf4, 0x5a, - 0xe9, 0x9d, 0xc4, 0x52, 0xc1, 0xc8, 0xb0, 0xe2, 0xba, 0x00, 0x2e, 0x5b, - 0x56, 0x7c, 0x27, 0xb7, 0x59, 0x2b, 0x2d, 0xa6, 0x6c, 0xaf, 0x12, 0x40, - 0x50, 0xa9, 0x54, 0x63, 0x05, 0x17, 0x8c, 0xb0, 0x83, 0x79, 0xaf, 0xc2, - 0x0b, 0x83, 0x56, 0x8e, 0xf2, 0x58, 0x91, 0x5c, 0x6b, 0xc5, 0xa3, 0x92, - 0x4a, 0x65, 0x28, 0x15, 0x8c, 0x73, 0x13, 0x59, 0xb1, 0x12, 0x4b, 0x05, - 0xdc, 0x60, 0xb5, 0xa2, 0x94, 0x6a, 0xc5, 0xec, 0x2a, 0x6e, 0xae, 0x74, - 0x63, 0xc5, 0xcf, 0x95, 0xf6, 0xb0, 0x12, 0xe6, 0x8a, 0x19, 0x2b, 0x32, - 0x55, 0xf2, 0x61, 0xa5, 0xd2, 0x0a, 0xc6, 0x9c, 0xa3, 0xac, 0x15, 0x8e, - 0x32, 0x3b, 0xa4, 0x83, 0x2b, 0x73, 0xe5, 0x38, 0x17, 0x0e, 0x09, 0x13, - 0x63, 0x68, 0xc5, 0x2a, 0x87, 0xa4, 0xc2, 0x0f, 0x73, 0x05, 0x03, 0x4e, - 0x92, 0xc9, 0x57, 0xdd, 0xa8, 0xaa, 0x20, 0x49, 0x36, 0x95, 0x1f, 0x6a, - 0x3e, 0x28, 0xa8, 0x40, 0x9c, 0xf0, 0x03, 0xd9, 0x7f, 0x0b, 0x79, 0x84, - 0x2c, 0x36, 0x54, 0x05, 0x62, 0x20, 0xbe, 0xbd, 0x6b, 0xeb, 0x01, 0x52, - 0x2a, 0xed, 0xca, 0xb8, 0x68, 0xd1, 0x57, 0x68, 0x0c, 0xdf, 0xf9, 0xf1, - 0x16, 0x4a, 0x38, 0x85, 0x59, 0x95, 0xcb, 0x39, 0x5a, 0x49, 0x60, 0xb1, - 0xb0, 0xee, 0x8d, 0xbd, 0x87, 0xf0, 0xe4, 0x40, 0x12, 0x7a, 0xbc, 0x48, - 0xe9, 0x1d, 0xc9, 0x50, 0x9a, 0xd8, 0x51, 0x32, 0xbd, 0x07, 0x71, 0x90, - 0x33, 0x15, 0x39, 0x23, 0xca, 0xf8, 0xe6, 0x37, 0x48, 0xc1, 0xbf, 0x54, - 0x92, 0xab, 0xce, 0x4b, 0xf7, 0x3b, 0x5a, 0xb2, 0x17, 0x39, 0x1c, 0xa7, - 0xb0, 0x8e, 0xe1, 0x34, 0x8a, 0xbb, 0x1e, 0xdc, 0x75, 0x92, 0x23, 0xa8, - 0x57, 0xf0, 0xd1, 0xc5, 0xd0, 0x28, 0x53, 0x65, 0xd7, 0x5b, 0x39, 0x86, - 0xb0, 0xc5, 0xd0, 0xba, 0x01, 0x13, 0x88, 0x1b, 0xd0, 0xb8, 0xef, 0x9a, - 0x01, 0x83, 0x45, 0x4e, 0xf4, 0xd1, 0xf5, 0x8d, 0x80, 0x0f, 0xa4, 0x87, - 0xbc, 0x42, 0x56, 0x9d, 0x74, 0x54, 0x6a, 0x0e, 0xc5, 0x11, 0x94, 0x36, - 0xc5, 0x15, 0x93, 0x9f, 0xd9, 0x2a, 0x18, 0x47, 0x3a, 0x3c, 0xdb, 0x73, - 0x7c, 0x44, 0x02, 0x3e, 0xab, 0xf2, 0xf9, 0xf4, 0xe9, 0xf7, 0xf2, 0x31, - 0x9f, 0x6d, 0x94, 0x4b, 0xf1, 0x83, 0x3c, 0xc8, 0x36, 0x85, 0xf3, 0x6c, - 0x93, 0xef, 0x31, 0x39, 0x3f, 0xf5, 0xe0, 0x22, 0x94, 0xdd, 0x09, 0x14, - 0xb2, 0x1f, 0x42, 0x04, 0xf9, 0xe6, 0xcf, 0xa9, 0x46, 0x4f, 0x7c, 0x82, - 0x7e, 0xbe, 0xc5, 0x1d, 0xcd, 0xa0, 0x77, 0xe8, 0xa1, 0x43, 0x5f, 0x6d, - 0xf4, 0x3f, 0xf2, 0x30, 0x35, 0x7d, 0x2e, 0x76, 0x08, 0xb7, 0x72, 0x96, - 0xf1, 0xda, 0xf5, 0xe0, 0xbb, 0xae, 0x28, 0x1d, 0x32, 0x26, 0xb9, 0xcf, - 0x54, 0x26, 0xfd, 0xe9, 0xcf, 0x4d, 0xd7, 0xa7, 0x4f, 0x76, 0x7d, 0x15, - 0x87, 0xb0, 0x3e, 0x7d, 0x90, 0xff, 0x91, 0xad, 0x48, 0xc2, 0x60, 0x83, - 0x3b, 0x55, 0xdd, 0x62, 0x52, 0x8a, 0xf2, 0xcd, 0xe4, 0x60, 0xa8, 0xf3, - 0x47, 0xd9, 0x86, 0x87, 0xf4, 0x28, 0xee, 0xe4, 0x22, 0xe1, 0xc9, 0xe3, - 0x2a, 0xfe, 0xc7, 0x6f, 0xb6, 0xfd, 0x4f, 0x33, 0x8c, 0xcd, 0xb6, 0x45, - 0x01, 0xad, 0xde, 0xfc, 0xca, 0x8b, 0xcf, 0x07, 0x6f, 0x8e, 0x03, 0x5e, - 0x77, 0x15, 0x3f, 0xbb, 0xe6, 0x82, 0x34, 0xd7, 0xdd, 0x5e, 0x23, 0x71, - 0x6e, 0xcd, 0x94, 0x6f, 0x1e, 0x85, 0xb5, 0x7c, 0x21, 0xa6, 0xf3, 0x17, - 0xac, 0x36, 0x7f, 0x21, 0x91, 0xf3, 0x17, 0x22, 0x38, 0x7f, 0x7d, 0xb7, - 0xfb, 0x86, 0x76, 0xf1, 0x9d, 0x9a, 0x3f, 0x78, 0xc3, 0xa2, 0xf9, 0x7a, - 0xd1, 0x7c, 0xb3, 0x68, 0xde, 0x2e, 0x9a, 0x77, 0x8b, 0xe6, 0xfd, 0x9b, - 0xcd, 0xab, 0x11, 0x84, 0x44, 0x42, 0x41, 0x40, 0xf0, 0x2b, 0x74, 0x32, - 0x08, 0x54, 0x20, 0xcd, 0xd6, 0x10, 0x7a, 0xd9, 0xc0, 0xe2, 0xe1, 0x57, - 0xdf, 0xb9, 0x9b, 0x54, 0x53, 0x31, 0x9f, 0xc1, 0xd6, 0x41, 0x72, 0xd4, - 0xf8, 0x36, 0x42, 0x6d, 0xdb, 0x41, 0x73, 0x02, 0x25, 0xa0, 0x11, 0x08, - 0xde, 0xaf, 0xba, 0x04, 0x93, 0x7b, 0x0f, 0x45, 0x0e, 0xe3, 0xbb, 0x89, - 0x85, 0xc2, 0xde, 0x5f, 0x43, 0x00, 0x0a, 0xf1, 0x7d, 0x61, 0xb0, 0x4a, - 0x1f, 0x88, 0xd4, 0x26, 0xb5, 0xea, 0x41, 0x8c, 0x1c, 0x94, 0x42, 0xb4, - 0xb0, 0xe1, 0xe7, 0x90, 0xf1, 0xc5, 0xe7, 0x5e, 0x52, 0x48, 0x36, 0x55, - 0x60, 0xca, 0x1e, 0x36, 0x5a, 0x70, 0x57, 0x0d, 0x76, 0xec, 0x7e, 0xe1, - 0x4f, 0x34, 0x12, 0x12, 0xa9, 0xed, 0x94, 0xf2, 0x73, 0xe5, 0x37, 0x10, - 0x99, 0x21, 0x65, 0x50, 0xc5, 0xa7, 0x3d, 0xba, 0x8a, 0xee, 0x63, 0x48, - 0x6a, 0xbd, 0xc7, 0xe8, 0x10, 0x61, 0x6c, 0xd0, 0xc7, 0x9e, 0x46, 0x8b, - 0x43, 0xb3, 0xbb, 0x06, 0xf8, 0xd3, 0x71, 0xe6, 0xc1, 0x08, 0x85, 0x35, - 0x12, 0xc1, 0x07, 0xbe, 0x78, 0x31, 0xbf, 0x30, 0x40, 0xa2, 0x9a, 0x77, - 0xfc, 0x82, 0x07, 0x3b, 0xf2, 0x02, 0x1e, 0xf0, 0x91, 0xcf, 0xb8, 0xc4, - 0x67, 0x0e, 0x1e, 0xab, 0xc4, 0x8c, 0x0f, 0x84, 0xd2, 0x76, 0xcf, 0xb6, - 0xc9, 0x85, 0x22, 0x4f, 0x22, 0xcf, 0x20, 0x97, 0x6a, 0x52, 0xe4, 0x4c, - 0x28, 0xe6, 0xbd, 0x36, 0x9a, 0xf7, 0xb8, 0x2b, 0x63, 0x82, 0xae, 0x0f, - 0xb9, 0xeb, 0xf6, 0x8d, 0x19, 0x6f, 0x49, 0x09, 0xde, 0xcb, 0x76, 0x40, - 0x0a, 0x6d, 0x9f, 0x2f, 0x35, 0xd1, 0xdf, 0x40, 0xa4, 0xb0, 0xf9, 0x56, - 0xa1, 0x5b, 0x24, 0x74, 0xab, 0x30, 0xdd, 0x1e, 0x0f, 0xa2, 0x17, 0xbc, - 0x09, 0x14, 0x8e, 0xcf, 0xd3, 0x56, 0xf2, 0x87, 0xb1, 0x41, 0xe9, 0xac, - 0xa4, 0xaa, 0xa8, 0x21, 0x45, 0x67, 0x98, 0x15, 0x89, 0x07, 0x64, 0x6c, - 0x62, 0xf3, 0x98, 0x95, 0xbb, 0x6e, 0xa0, 0x75, 0x67, 0xd1, 0x00, 0x77, - 0xe5, 0xc2, 0x5d, 0xbd, 0x72, 0x57, 0x34, 0xfa, 0x2e, 0xa2, 0x3b, 0xbc, - 0xd6, 0xa8, 0x49, 0x35, 0x04, 0x90, 0xa4, 0x09, 0x16, 0x04, 0x74, 0xe1, - 0xca, 0xa0, 0x26, 0xaf, 0x51, 0x3b, 0x6b, 0xa8, 0xf9, 0x30, 0xdf, 0xb8, - 0x82, 0x81, 0xc4, 0xe9, 0x13, 0x46, 0xf9, 0x16, 0xa3, 0x7e, 0xd6, 0x99, - 0x15, 0x94, 0x21, 0xac, 0xa6, 0xdd, 0xc0, 0x94, 0xa2, 0xb7, 0x40, 0x48, - 0xcd, 0x35, 0xcc, 0xeb, 0x3a, 0x9a, 0x95, 0xef, 0x6a, 0x18, 0x39, 0x7b, - 0x31, 0x18, 0x0f, 0xd3, 0x36, 0xd0, 0x32, 0x41, 0x76, 0x61, 0xee, 0xb2, - 0x8d, 0x75, 0xf2, 0x9d, 0x85, 0x29, 0xf0, 0x30, 0x6d, 0xd0, 0xd1, 0xc0, - 0xd6, 0x9d, 0x83, 0xb9, 0x03, 0xe2, 0x81, 0xb7, 0x00, 0x8b, 0xed, 0x3b, - 0x05, 0x44, 0x35, 0x10, 0x39, 0x14, 0x79, 0xeb, 0xf7, 0x95, 0xdb, 0xde, - 0x47, 0x95, 0x06, 0x07, 0xab, 0x9e, 0x10, 0xc5, 0x97, 0x4e, 0x31, 0xa7, - 0xc0, 0xba, 0x10, 0xb8, 0xb5, 0xc0, 0x10, 0x72, 0x72, 0xef, 0x94, 0x73, - 0x07, 0x68, 0x1b, 0xdc, 0x39, 0xf3, 0x48, 0x3d, 0xe8, 0x04, 0xb2, 0xef, - 0xcb, 0x0b, 0x80, 0xd4, 0xcf, 0x13, 0xbb, 0xcf, 0x4d, 0x6d, 0x86, 0x70, - 0x33, 0xb8, 0xfb, 0x81, 0x57, 0x07, 0x21, 0xcc, 0x96, 0x75, 0x1b, 0xde, - 0x6f, 0xac, 0x5c, 0x18, 0x25, 0x00, 0xa6, 0x5b, 0x88, 0x35, 0xad, 0xe2, - 0x6f, 0x88, 0x46, 0xad, 0x4c, 0xd8, 0x12, 0xa7, 0x9f, 0x41, 0x9e, 0x92, - 0xbf, 0x51, 0x87, 0xa6, 0xbc, 0x19, 0x93, 0x0a, 0x0c, 0x91, 0x38, 0xa1, - 0x70, 0x36, 0x54, 0x16, 0x96, 0x7a, 0xd1, 0x2b, 0xe7, 0x52, 0x2f, 0x42, - 0x1a, 0xd7, 0xe4, 0x5c, 0xb3, 0xd0, 0x8b, 0xa7, 0x45, 0x21, 0x81, 0x65, - 0xb6, 0x11, 0x2e, 0x07, 0xa0, 0x26, 0x99, 0x5a, 0xb9, 0x02, 0x62, 0xd2, - 0x8c, 0x56, 0x8e, 0xac, 0x87, 0x69, 0xd8, 0x8e, 0x2d, 0xb1, 0xaf, 0x37, - 0xc5, 0xbf, 0xda, 0x8a, 0x7f, 0x62, 0x37, 0x27, 0x51, 0x38, 0x60, 0xca, - 0xfc, 0x36, 0xbf, 0xce, 0x97, 0x00, 0x85, 0xe1, 0x8a, 0x34, 0x60, 0x24, - 0x8c, 0x16, 0x9b, 0x79, 0x06, 0x85, 0x67, 0xd1, 0x5d, 0xc3, 0x56, 0x07, - 0x9d, 0x1c, 0xe8, 0x45, 0xda, 0x57, 0x34, 0x42, 0x85, 0x61, 0x44, 0x6d, - 0xc9, 0x5b, 0x3c, 0x10, 0x8b, 0xb4, 0xed, 0xc4, 0x67, 0x98, 0xa4, 0x90, - 0x5d, 0xb1, 0xa3, 0x74, 0xed, 0xdd, 0xe5, 0xe7, 0xbb, 0xf4, 0xd0, 0x7e, - 0xf9, 0xe6, 0x5e, 0xf9, 0x67, 0xd1, 0x72, 0x19, 0xa4, 0xf1, 0x19, 0x97, - 0xe6, 0x67, 0x46, 0xa1, 0x15, 0x15, 0xae, 0x7a, 0x41, 0x14, 0x06, 0x76, - 0x71, 0xd8, 0x7b, 0xb9, 0x8c, 0xed, 0xed, 0x1d, 0x54, 0xcb, 0x71, 0x00, - 0xa3, 0x9d, 0x6d, 0x9d, 0x23, 0xc3, 0x62, 0x80, 0xba, 0x00, 0x4b, 0xf2, - 0x94, 0xa7, 0x29, 0x78, 0x2e, 0xb6, 0xee, 0x85, 0xfd, 0xd9, 0x5d, 0x2a, - 0xf6, 0x87, 0x4f, 0xdd, 0x01, 0x93, 0xbb, 0x3e, 0x5c, 0x64, 0x47, 0x26, - 0xa9, 0xf5, 0x81, 0x4e, 0xf5, 0xb4, 0xd0, 0x9d, 0x71, 0x49, 0x21, 0x1b, - 0xb0, 0xa5, 0xc3, 0x64, 0x0c, 0x35, 0xbd, 0xd1, 0x2d, 0xdf, 0x65, 0xa6, - 0xe9, 0x7e, 0x67, 0x76, 0x95, 0x8c, 0xc2, 0x5a, 0x85, 0x42, 0x68, 0xa3, - 0xc1, 0x92, 0x6b, 0x66, 0x6d, 0x74, 0x68, 0xeb, 0x42, 0xb7, 0x6f, 0xd4, - 0xfd, 0x74, 0x6f, 0x1e, 0xd5, 0x6e, 0x9e, 0x8c, 0x7a, 0x2e, 0xd6, 0xf4, - 0x6b, 0x6c, 0xf0, 0xc3, 0xfc, 0xd4, 0xd3, 0xa0, 0x0e, 0x30, 0xbc, 0xec, - 0x01, 0xdd, 0x3b, 0x55, 0x61, 0x22, 0x53, 0x5f, 0xaa, 0x40, 0x09, 0x5e, - 0xde, 0x87, 0x87, 0xc1, 0xc4, 0x17, 0x7a, 0x1c, 0x3d, 0xe7, 0x53, 0xca, - 0xa1, 0x70, 0xa5, 0x17, 0x83, 0x52, 0x41, 0x40, 0xfc, 0x65, 0x6a, 0xa0, - 0xf5, 0xe8, 0xcd, 0x5f, 0x03, 0xca, 0xfa, 0xd2, 0x92, 0xd0, 0xf8, 0x51, - 0xb0, 0x3b, 0x5b, 0x3a, 0x0a, 0x07, 0x64, 0x9f, 0x61, 0xdf, 0xf8, 0xd8, - 0xb7, 0x59, 0xfc, 0x8d, 0x0f, 0x08, 0x0b, 0xdb, 0x87, 0xb1, 0x60, 0xb4, - 0x87, 0x71, 0x9b, 0xf8, 0xd9, 0x5b, 0xc0, 0xc2, 0x95, 0xc3, 0x0d, 0x7f, - 0x32, 0xe6, 0x6f, 0xa6, 0xea, 0x18, 0x8b, 0x18, 0x54, 0x05, 0x76, 0x0d, - 0xa6, 0x0e, 0x33, 0x0e, 0x13, 0x7d, 0x44, 0x3a, 0x5b, 0x4a, 0x5a, 0xe7, - 0x31, 0x60, 0x3d, 0xba, 0x6d, 0x19, 0x14, 0x31, 0xb4, 0x52, 0xb4, 0x04, - 0xf8, 0x35, 0xe8, 0x97, 0xf3, 0x8c, 0x11, 0x4c, 0x6a, 0xf7, 0x3b, 0x5c, - 0x24, 0x72, 0x8c, 0xd4, 0x3e, 0xd6, 0x98, 0x3f, 0x1b, 0xf3, 0xdb, 0x4b, - 0x92, 0xfb, 0x03, 0x4a, 0xc3, 0xfe, 0xe5, 0xdc, 0x9a, 0x5a, 0x23, 0x0a, - 0x9f, 0x08, 0xee, 0xf8, 0xe6, 0x81, 0x76, 0x87, 0xaf, 0xc0, 0x7c, 0x82, - 0x9f, 0x30, 0x89, 0xbd, 0x7e, 0x31, 0x88, 0xbc, 0x48, 0x43, 0x0f, 0x6d, - 0xcf, 0x37, 0x3b, 0x12, 0x01, 0xcb, 0xa4, 0x94, 0x07, 0xa8, 0xc2, 0x3e, - 0x80, 0x99, 0x23, 0x09, 0xa6, 0xe3, 0x54, 0x33, 0x62, 0xc4, 0x76, 0x7b, - 0xbe, 0xc2, 0x68, 0x6f, 0xa8, 0x59, 0x1d, 0x3d, 0x27, 0xcc, 0x11, 0xe6, - 0x3d, 0x07, 0x45, 0x2b, 0xfc, 0x1e, 0x8d, 0x5f, 0x79, 0xef, 0x5b, 0x60, - 0xc8, 0xee, 0x3b, 0xc2, 0x93, 0x4c, 0x99, 0x26, 0x7d, 0x80, 0x6c, 0x69, - 0x22, 0x9b, 0x83, 0xdc, 0xec, 0x83, 0xeb, 0xe5, 0xf7, 0xcd, 0xd9, 0x7c, - 0xe3, 0xfe, 0xc5, 0x83, 0x54, 0x20, 0x8a, 0x09, 0xe8, 0x80, 0xaa, 0xd3, - 0x2c, 0xf4, 0x89, 0x21, 0x58, 0x54, 0x37, 0x42, 0xc8, 0x1f, 0x62, 0x35, - 0xe1, 0xa4, 0x82, 0x2b, 0x6a, 0x0d, 0xba, 0x34, 0x1a, 0x9e, 0x61, 0x59, - 0x47, 0x9a, 0xc6, 0x9a, 0xee, 0x30, 0x58, 0x93, 0x7e, 0x90, 0x19, 0x4a, - 0x09, 0x33, 0x9d, 0x51, 0x42, 0xa2, 0xbb, 0x95, 0xa7, 0x24, 0xad, 0x02, - 0xde, 0xc5, 0x52, 0xb4, 0xcc, 0x75, 0xfc, 0x14, 0x60, 0x99, 0xa3, 0x5f, - 0x55, 0x09, 0x65, 0xae, 0x4b, 0x19, 0x17, 0x65, 0xcf, 0xb2, 0x39, 0x2c, - 0x87, 0xef, 0x28, 0xd1, 0x42, 0xb3, 0x57, 0x7e, 0xd2, 0x72, 0x05, 0x17, - 0x9e, 0x25, 0xbb, 0xb3, 0x5a, 0xd5, 0xf1, 0x2f, 0xf0, 0xdb, 0xaa, 0xf4, - 0x97, 0x67, 0x94, 0xb0, 0x54, 0x09, 0x34, 0x27, 0x81, 0x73, 0x8f, 0x1a, - 0x40, 0x04, 0xfe, 0xc3, 0xeb, 0xf7, 0xbd, 0xeb, 0x1c, 0xb0, 0x47, 0xf1, - 0xfe, 0x4a, 0xa0, 0xa1, 0x00, 0x85, 0x12, 0x98, 0x30, 0xe3, 0xec, 0xd4, - 0x3a, 0xca, 0x1c, 0x3d, 0xd3, 0x12, 0x15, 0x35, 0x2d, 0xc5, 0x58, 0x75, - 0x55, 0x89, 0x3e, 0x88, 0x42, 0x25, 0x51, 0xfc, 0x24, 0x1a, 0x08, 0xe0, - 0x2c, 0x10, 0xdf, 0xcd, 0xfc, 0x9e, 0x14, 0x44, 0x55, 0x1a, 0x4c, 0x40, - 0x0b, 0x34, 0x18, 0x04, 0x7b, 0x9c, 0x20, 0xc2, 0x01, 0x1a, 0x7f, 0xa8, - 0x40, 0xc5, 0x59, 0x04, 0x57, 0x34, 0xe2, 0x68, 0xff, 0xac, 0x65, 0x38, - 0xa8, 0xca, 0xe0, 0xac, 0x67, 0xb0, 0x16, 0xd1, 0xd5, 0x0d, 0x60, 0x22, - 0x10, 0x16, 0x63, 0x14, 0xc2, 0x18, 0x0e, 0xa0, 0x15, 0x00, 0x0b, 0xf5, - 0x8e, 0xbd, 0xca, 0xc6, 0x03, 0x62, 0x85, 0x63, 0xf0, 0x3d, 0x63, 0x41, - 0xc0, 0x56, 0x83, 0xc3, 0x4c, 0x03, 0x5f, 0xf5, 0x81, 0xc0, 0x09, 0xb6, - 0x2d, 0x33, 0x12, 0x53, 0x11, 0x5c, 0x0d, 0x0d, 0xb4, 0x95, 0x8d, 0x50, - 0xee, 0x40, 0x5c, 0xb0, 0xee, 0xe5, 0x86, 0x23, 0x46, 0x90, 0xa0, 0xb6, - 0x1b, 0xe0, 0x03, 0x74, 0x2c, 0xf9, 0xa2, 0x12, 0xe9, 0x43, 0x42, 0x0d, - 0xcb, 0x85, 0x68, 0x74, 0x90, 0xe6, 0x27, 0x7b, 0xb0, 0x52, 0x68, 0x09, - 0x23, 0x80, 0x76, 0x34, 0x60, 0xe2, 0x48, 0xdc, 0x96, 0xc8, 0xaa, 0xd7, - 0xb8, 0x8c, 0x50, 0x34, 0xb2, 0xc6, 0x69, 0x40, 0xa0, 0x9a, 0x2f, 0xa0, - 0x37, 0xa2, 0x08, 0xb6, 0xb7, 0x56, 0xb4, 0x45, 0xb5, 0x3e, 0x40, 0x8b, - 0x6e, 0xa8, 0x9d, 0xa9, 0x93, 0x3f, 0x7a, 0xd8, 0x10, 0xc1, 0xf0, 0xd0, - 0xf0, 0xf1, 0xb1, 0x31, 0x3b, 0xa3, 0x85, 0x7e, 0x7a, 0x43, 0x2b, 0xe5, - 0x96, 0xf1, 0x39, 0x58, 0xae, 0x4a, 0xad, 0xd4, 0xb7, 0x1d, 0xc6, 0x56, - 0xc2, 0x6d, 0x52, 0x4b, 0xb6, 0x29, 0x30, 0x68, 0xad, 0x3d, 0xca, 0xa5, - 0x7f, 0xbd, 0x9a, 0x0b, 0xff, 0x25, 0xf7, 0x61, 0x67, 0xb0, 0x97, 0xc6, - 0xea, 0x63, 0xe8, 0x49, 0x61, 0xc9, 0x88, 0x5a, 0x46, 0xd7, 0x60, 0x84, - 0x24, 0xaf, 0x5e, 0xfa, 0x20, 0x1c, 0xdb, 0xb3, 0x99, 0xdb, 0xa5, 0xfb, - 0xb0, 0xe7, 0x9c, 0xe6, 0x7d, 0x83, 0xfd, 0xce, 0x9c, 0xee, 0x4d, 0xd8, - 0x77, 0x0e, 0xfc, 0x0f, 0x3f, 0x14, 0x92, 0x16, 0x04, 0x86, 0xcd, 0x3c, - 0xa7, 0x23, 0x2b, 0xc5, 0xc2, 0x4a, 0x6d, 0xe1, 0x65, 0x38, 0x8a, 0xb7, - 0xf4, 0x10, 0xf3, 0x5c, 0xed, 0x69, 0x4d, 0x32, 0x91, 0x81, 0xff, 0xea, - 0xea, 0x8b, 0xc6, 0x50, 0xfd, 0xe6, 0xc6, 0x4a, 0xf5, 0x55, 0xb0, 0xf0, - 0xaa, 0xbb, 0xf4, 0xad, 0x2f, 0xc8, 0x3f, 0x7a, 0x14, 0xbe, 0x50, 0xdd, - 0xb9, 0x32, 0xf0, 0x82, 0x68, 0x74, 0xc7, 0x10, 0xcf, 0xb5, 0xa2, 0x41, - 0x4c, 0x96, 0xfa, 0x2b, 0x33, 0xe4, 0x9b, 0xf9, 0x99, 0x11, 0x5b, 0x6a, - 0x9c, 0x20, 0xad, 0xd5, 0xc0, 0x04, 0x55, 0xa9, 0x3a, 0x48, 0x52, 0x82, - 0xb9, 0xaf, 0x8a, 0x4a, 0x4d, 0xcc, 0xa7, 0xb3, 0x7d, 0x54, 0x9c, 0xa6, - 0x46, 0x87, 0x2e, 0xbd, 0xdf, 0xe0, 0x7c, 0xe9, 0x40, 0xac, 0x88, 0x3c, - 0x0b, 0x50, 0xf4, 0x0f, 0xd9, 0x02, 0x63, 0x80, 0xb1, 0x32, 0x18, 0x6b, - 0xeb, 0xe4, 0xfe, 0x4a, 0xf2, 0x67, 0x07, 0xcf, 0x50, 0xba, 0x58, 0x11, - 0x60, 0xfd, 0x74, 0x8e, 0x7f, 0xeb, 0xf3, 0x8b, 0xc5, 0x2e, 0xbe, 0x4d, - 0xc9, 0x57, 0x7f, 0x8a, 0x9a, 0x05, 0x10, 0x6c, 0x86, 0x39, 0xac, 0xf2, - 0x0f, 0x39, 0x21, 0x7f, 0x52, 0x2f, 0xc2, 0x71, 0xef, 0xdf, 0x3f, 0x61, - 0x16, 0x2e, 0x3a, 0x38, 0x42, 0x8f, 0x72, 0x42, 0x9f, 0xc3, 0x6a, 0xcc, - 0x0c, 0xbc, 0x97, 0x54, 0xfb, 0x66, 0x4d, 0x2d, 0x30, 0xb0, 0x66, 0xc9, - 0x68, 0xd4, 0x99, 0x0c, 0xb4, 0x61, 0xec, 0xee, 0xc1, 0xed, 0x6b, 0x28, - 0x2a, 0xdf, 0xc3, 0x29, 0x6b, 0xe1, 0xb6, 0x55, 0x62, 0x61, 0xd8, 0xa0, - 0xa4, 0x7b, 0x68, 0xa8, 0xe3, 0x5c, 0x6b, 0x7c, 0x1d, 0x4e, 0x7e, 0x37, - 0x9e, 0x30, 0xea, 0xee, 0xaf, 0xc0, 0x81, 0x27, 0xf0, 0x53, 0x5c, 0xe4, - 0x53, 0xf0, 0x4b, 0x4a, 0x23, 0xa1, 0x63, 0x20, 0xc0, 0xc3, 0x5e, 0x83, - 0x3f, 0xa9, 0xfc, 0xf0, 0x72, 0x3a, 0x98, 0x14, 0x28, 0x4a, 0x53, 0x39, - 0xdd, 0x5d, 0xd5, 0x9b, 0x41, 0xd5, 0x69, 0x9c, 0x08, 0xf0, 0xd7, 0x8b, - 0x96, 0xc3, 0x8e, 0x88, 0x66, 0x18, 0xc9, 0xd8, 0x51, 0x65, 0x41, 0x24, - 0xa6, 0x9e, 0x34, 0xcf, 0x5d, 0x18, 0x7b, 0x04, 0x31, 0xae, 0xa6, 0x77, - 0x3c, 0x65, 0xcd, 0x1a, 0x82, 0xfe, 0x9f, 0xa1, 0x4e, 0x7e, 0x78, 0xf5, - 0xe5, 0xa7, 0x53, 0x74, 0xa7, 0x30, 0x8f, 0x58, 0x5c, 0x41, 0x78, 0x20, - 0x06, 0xf7, 0xa2, 0x58, 0xaf, 0x60, 0xc5, 0x9e, 0x50, 0x51, 0x23, 0x8f, - 0x4c, 0xd4, 0x2a, 0x3c, 0x52, 0x9c, 0xa4, 0xf9, 0x2b, 0x8d, 0x3d, 0xb2, - 0x09, 0xcf, 0x7b, 0x1c, 0xef, 0x71, 0xbc, 0x07, 0x8f, 0x9c, 0xb5, 0x8d, - 0x94, 0xd9, 0x91, 0xbe, 0x82, 0xea, 0x8d, 0xd5, 0xb3, 0x3c, 0x27, 0x93, - 0x05, 0xe8, 0x30, 0x04, 0xc0, 0x44, 0x7f, 0x86, 0x7b, 0xdc, 0xa9, 0x6c, - 0x3b, 0xbb, 0x91, 0x9b, 0xde, 0xde, 0xc8, 0x7d, 0x6a, 0xee, 0xe5, 0x71, - 0xa8, 0x1f, 0x65, 0xc8, 0x55, 0x82, 0xda, 0x34, 0x30, 0xe6, 0xae, 0x05, - 0xdb, 0xad, 0xbb, 0xe0, 0xe4, 0x32, 0xfa, 0xb5, 0x5c, 0x27, 0x77, 0x22, - 0x77, 0x83, 0xbd, 0x90, 0xb4, 0x6a, 0xae, 0xe0, 0x11, 0x35, 0x77, 0x92, - 0xdd, 0x05, 0x14, 0x95, 0xbd, 0x02, 0xf2, 0x3b, 0x89, 0xf0, 0x91, 0xce, - 0xe1, 0x3d, 0x4a, 0x3f, 0x04, 0xa8, 0xbf, 0xe0, 0x4f, 0x00, 0x0a, 0x4f, - 0x8f, 0xe1, 0x3d, 0x6d, 0xce, 0xa1, 0x25, 0x6f, 0x80, 0x0b, 0xea, 0x7b, - 0xa8, 0xe6, 0x23, 0x62, 0xc5, 0x4e, 0x12, 0x6e, 0x0c, 0x50, 0xa3, 0xd1, - 0x41, 0x83, 0x82, 0xa5, 0x6b, 0x06, 0xa7, 0x8e, 0x18, 0x5e, 0xe8, 0x08, - 0x85, 0x3a, 0x68, 0x4a, 0x30, 0x0b, 0x5c, 0x4c, 0x78, 0x9c, 0xbd, 0xc3, - 0x0d, 0xd1, 0x32, 0x7a, 0xd5, 0xc0, 0x07, 0x05, 0xea, 0x24, 0xff, 0x97, - 0x08, 0x71, 0xcb, 0x18, 0x31, 0xf3, 0x67, 0x80, 0xe8, 0x3d, 0xa0, 0xaf, - 0x46, 0x47, 0xbb, 0x4a, 0x87, 0x82, 0x59, 0x74, 0xe5, 0x52, 0xa7, 0x4a, - 0x18, 0xba, 0x98, 0x7a, 0x97, 0x1a, 0xa6, 0xb3, 0x0a, 0x64, 0x68, 0x10, - 0x60, 0x17, 0xd8, 0x12, 0x6d, 0x07, 0x9a, 0x21, 0x0a, 0xa3, 0x1b, 0x8e, - 0xf7, 0x53, 0xd5, 0x83, 0x4a, 0xd2, 0x13, 0x1a, 0x79, 0x02, 0xd5, 0xdb, - 0x0e, 0x43, 0xd3, 0x60, 0xb4, 0xbc, 0x9c, 0x9e, 0x0b, 0xbb, 0x79, 0x8d, - 0x9e, 0x3b, 0x8c, 0x08, 0x06, 0x09, 0x23, 0x91, 0xdd, 0x0d, 0x3b, 0x2e, - 0xc7, 0x18, 0x47, 0x77, 0x8b, 0xfe, 0x05, 0x39, 0x7e, 0xd2, 0xc4, 0x5b, - 0xbf, 0x68, 0x2e, 0x68, 0x0c, 0x05, 0xdd, 0xa2, 0xb8, 0x33, 0x88, 0xd2, - 0xbb, 0x25, 0x31, 0xc4, 0x5e, 0xc4, 0x59, 0xad, 0x53, 0x7b, 0xd1, 0x4f, - 0xf4, 0x6b, 0x57, 0x14, 0x2b, 0xd2, 0x8a, 0xd4, 0x3a, 0xe1, 0xbd, 0x59, - 0xcd, 0xf9, 0x8d, 0x37, 0x8c, 0x9f, 0x7d, 0x7a, 0x35, 0xde, 0xf1, 0x51, - 0x5b, 0xf5, 0x83, 0x2f, 0xbd, 0x84, 0x90, 0x63, 0xd8, 0xe5, 0xac, 0x40, - 0x48, 0x51, 0x64, 0x78, 0x55, 0xb2, 0x95, 0xef, 0x43, 0x48, 0x45, 0x61, - 0x6f, 0x40, 0xc8, 0xfc, 0x55, 0x06, 0xa7, 0x3c, 0xb0, 0xf3, 0x1c, 0x9a, - 0x4c, 0x7f, 0x60, 0x7c, 0xc3, 0xa1, 0xcb, 0xd0, 0x4a, 0x9e, 0x43, 0x7f, - 0x3f, 0xe1, 0x60, 0xfe, 0x49, 0xe6, 0x54, 0x8a, 0x0f, 0xbd, 0x77, 0xa8, - 0xca, 0xba, 0x0e, 0x2e, 0x85, 0xf9, 0x77, 0xb8, 0xd2, 0xa6, 0x48, 0x63, - 0x5f, 0x86, 0x3f, 0xc9, 0xec, 0x48, 0x95, 0x19, 0xfa, 0xfa, 0xe9, 0x7e, - 0x31, 0xcf, 0xfb, 0x13, 0xdc, 0x2d, 0x5e, 0xa4, 0x7c, 0xe5, 0x37, 0x7b, - 0x6f, 0xd8, 0x3f, 0xfc, 0x58, 0xc8, 0xb3, 0x17, 0xbd, 0xad, 0x8b, 0x33, - 0xe8, 0x38, 0xeb, 0xdb, 0x01, 0xa6, 0x6e, 0x1d, 0xed, 0x7d, 0x1e, 0xe3, - 0x8a, 0xf4, 0xf1, 0xc3, 0x59, 0x67, 0x1f, 0xc6, 0xa0, 0xf8, 0x22, 0x22, - 0x4f, 0x57, 0x37, 0x9c, 0x26, 0x7b, 0x5f, 0x32, 0x44, 0x8d, 0x06, 0x76, - 0x34, 0x3d, 0x23, 0xf3, 0xc1, 0x89, 0x66, 0x66, 0xa6, 0x43, 0xd6, 0x68, - 0x83, 0x1e, 0x3a, 0xc6, 0xa3, 0x18, 0x06, 0x72, 0x4f, 0x5c, 0x07, 0x34, - 0xc5, 0x30, 0x5f, 0x4c, 0x6d, 0xf1, 0x0e, 0xa7, 0x59, 0x9f, 0xa2, 0xa4, - 0x05, 0xc6, 0xee, 0x32, 0x95, 0x7b, 0x11, 0xf9, 0x37, 0x82, 0x9a, 0xd3, - 0xa7, 0x65, 0x62, 0x4b, 0xc3, 0x62, 0x03, 0xc5, 0xc0, 0x71, 0x79, 0x06, - 0x41, 0xd3, 0x1f, 0xf2, 0xe7, 0x3f, 0x82, 0x57, 0xfa, 0x7d, 0xde, 0xec, - 0x2c, 0x04, 0x98, 0xe3, 0x9b, 0xac, 0xf9, 0x93, 0x0b, 0x66, 0x7e, 0x8a, - 0xba, 0x29, 0xc6, 0xb1, 0x63, 0xa4, 0xa9, 0x1a, 0x4c, 0x89, 0xcd, 0xd0, - 0x59, 0x21, 0xd8, 0x63, 0xd6, 0x47, 0x43, 0x37, 0xa7, 0x3d, 0xf3, 0x43, - 0xd5, 0x18, 0xd9, 0x21, 0xf0, 0x73, 0xd7, 0x63, 0x5c, 0xe9, 0x04, 0x73, - 0xcc, 0xa5, 0x45, 0xae, 0xaf, 0x07, 0x82, 0x40, 0x70, 0x66, 0xff, 0x4a, - 0xd8, 0x08, 0xa8, 0x34, 0xda, 0xe8, 0xfa, 0x29, 0xae, 0x14, 0x5a, 0xd1, - 0xa0, 0x13, 0x6e, 0x00, 0x3c, 0x8c, 0xb8, 0xa1, 0xc4, 0xa4, 0xb8, 0xd2, - 0xa5, 0x07, 0x9f, 0x9f, 0x83, 0xf1, 0xb4, 0x79, 0x30, 0x12, 0xd7, 0x29, - 0xb9, 0x5d, 0x44, 0xeb, 0x6e, 0x8a, 0x2b, 0x61, 0xb6, 0x36, 0x98, 0xae, - 0x53, 0xcc, 0x17, 0x57, 0xeb, 0x80, 0xf6, 0xe7, 0x31, 0xae, 0x34, 0x86, - 0xcb, 0x9c, 0xe6, 0x23, 0x17, 0x11, 0xb5, 0xa4, 0x52, 0xc0, 0xfc, 0x6a, - 0x33, 0x07, 0xdc, 0xca, 0xba, 0x1d, 0x9f, 0x54, 0x78, 0x0c, 0xbd, 0x60, - 0xc3, 0x95, 0x36, 0x5a, 0xe6, 0x65, 0x19, 0xda, 0xb1, 0x4c, 0xbb, 0xd2, - 0xbd, 0x56, 0x0e, 0x2c, 0x6b, 0xc6, 0x48, 0x07, 0x94, 0x5d, 0x29, 0xfd, - 0xdb, 0x25, 0xfa, 0xcd, 0x30, 0xa9, 0x1b, 0xcb, 0xb0, 0x2a, 0x65, 0x93, - 0x30, 0x92, 0x8b, 0x72, 0x55, 0xca, 0xc0, 0x45, 0x4a, 0x28, 0xa3, 0xed, - 0xb3, 0x7f, 0xb5, 0xe4, 0xaa, 0x4e, 0x2d, 0xd7, 0x63, 0xd9, 0xdc, 0x0d, - 0x6e, 0xdd, 0xef, 0x97, 0x69, 0xaf, 0xdc, 0xf4, 0xcd, 0xa3, 0x96, 0x4f, - 0xc9, 0x6e, 0xfa, 0x1a, 0xe5, 0xb6, 0x94, 0x5d, 0xfd, 0x14, 0xf7, 0x4a, - 0x99, 0x4a, 0x6a, 0x87, 0xb1, 0xac, 0xc6, 0xb2, 0x9f, 0xca, 0xf6, 0xa0, - 0xac, 0xf7, 0x4b, 0xc3, 0x07, 0x97, 0xa5, 0x39, 0x28, 0xab, 0x5d, 0x49, - 0x49, 0xd4, 0xec, 0x0f, 0x17, 0x5e, 0xb9, 0x1b, 0x1d, 0x63, 0x7f, 0x9d, - 0x74, 0xe8, 0x2e, 0x30, 0x82, 0x18, 0xa9, 0xa3, 0xac, 0x83, 0xc4, 0x83, - 0x05, 0xef, 0x08, 0x3b, 0x0f, 0xf6, 0x03, 0x47, 0x3d, 0x66, 0xf2, 0x6e, - 0x8d, 0x83, 0x07, 0xf5, 0x0a, 0xa3, 0x94, 0xd3, 0x9d, 0x68, 0xb4, 0x76, - 0x5c, 0x1c, 0x69, 0x8b, 0xe2, 0x6c, 0x64, 0x2f, 0x0d, 0x37, 0x26, 0xf2, - 0xb2, 0xf2, 0x84, 0x1e, 0x96, 0xda, 0xb4, 0x2e, 0x99, 0xf9, 0x72, 0xe8, - 0x98, 0xa8, 0x04, 0x1f, 0xf2, 0x7d, 0x72, 0xda, 0xdb, 0x98, 0x47, 0x22, - 0x2a, 0x69, 0xe2, 0x48, 0x19, 0x0e, 0x70, 0x7c, 0xd2, 0x48, 0x35, 0xa4, - 0xe4, 0xb2, 0xb0, 0xcb, 0x0d, 0xd1, 0x7a, 0xab, 0x0a, 0x53, 0x4c, 0x13, - 0xd9, 0x32, 0x8e, 0x74, 0x7b, 0xc0, 0xe3, 0x74, 0xaf, 0x80, 0x01, 0xd8, - 0x1a, 0x7c, 0xaa, 0x9e, 0x8e, 0x1d, 0x24, 0x64, 0x92, 0xb0, 0x16, 0x02, - 0xbc, 0x88, 0xdb, 0x0e, 0x74, 0xba, 0x16, 0x22, 0x74, 0x8d, 0xe7, 0x2f, - 0x81, 0x25, 0xd7, 0x91, 0x44, 0x31, 0x91, 0x4a, 0x4e, 0xd6, 0x98, 0xf1, - 0x81, 0x8c, 0x30, 0x85, 0xef, 0xb3, 0x29, 0x0b, 0x98, 0x92, 0x76, 0xb8, - 0xd2, 0xb8, 0x75, 0xab, 0x86, 0x9b, 0x43, 0x41, 0xb8, 0xe2, 0x62, 0x59, - 0xda, 0x16, 0x3a, 0x85, 0x2e, 0x9c, 0x1e, 0x46, 0xc1, 0x7f, 0xf8, 0xe5, - 0xc0, 0x38, 0xd2, 0xb3, 0x86, 0x92, 0x1e, 0x34, 0x9a, 0xb4, 0x15, 0xf5, - 0xb1, 0x66, 0x25, 0x3d, 0x69, 0xe8, 0x26, 0xef, 0xb4, 0xb6, 0xb2, 0x4b, - 0xb9, 0xc9, 0xa5, 0x59, 0x8d, 0xcf, 0x4f, 0xf9, 0x0f, 0x3f, 0x55, 0x7d, - 0xc5, 0x53, 0x13, 0x75, 0x67, 0x5c, 0x27, 0x32, 0x13, 0xfd, 0x22, 0xa0, - 0x81, 0x16, 0xa0, 0x7b, 0x7b, 0xce, 0x0f, 0x7c, 0x9a, 0x5c, 0xfd, 0xa2, - 0x1f, 0xf6, 0x3e, 0x83, 0xe8, 0xba, 0xd8, 0x79, 0xe9, 0x94, 0x6f, 0xf7, - 0x16, 0x6d, 0xb9, 0xc5, 0x6a, 0x2b, 0xdb, 0xef, 0x56, 0x61, 0x35, 0x71, - 0x2f, 0xbb, 0xb4, 0x5c, 0x17, 0x56, 0x0d, 0xbb, 0x05, 0x5d, 0xa6, 0x2c, - 0x5f, 0x98, 0xbf, 0xcb, 0x35, 0x60, 0xcb, 0x37, 0xb9, 0xee, 0xf5, 0xd7, - 0xd8, 0x83, 0xd7, 0xa4, 0x2f, 0xbc, 0xe6, 0x70, 0x6c, 0x7f, 0xed, 0xbf, - 0x83, 0xb7, 0x87, 0xa8, 0x62, 0xe2, 0xf3, 0xb8, 0x00, 0xa6, 0x35, 0xa3, - 0x6c, 0xf9, 0xb3, 0xb6, 0x7a, 0xa6, 0x09, 0x55, 0xc9, 0x83, 0xd6, 0x35, - 0x7e, 0xdd, 0xd3, 0x86, 0x39, 0xc8, 0xa5, 0x40, 0x96, 0x63, 0x30, 0xe1, - 0x98, 0x0a, 0xac, 0xa7, 0xb4, 0x8a, 0xa6, 0x5d, 0x20, 0xd7, 0x42, 0x59, - 0x86, 0x95, 0x3c, 0x57, 0x1d, 0xd2, 0x24, 0x48, 0xfa, 0x25, 0x6c, 0x28, - 0x04, 0x9f, 0x5a, 0x6c, 0x43, 0x6b, 0xd4, 0xda, 0x87, 0xe2, 0x2d, 0xe6, - 0xd7, 0xd0, 0x15, 0xf8, 0x70, 0x9d, 0xc2, 0xc9, 0x00, 0x3d, 0xe3, 0xba, - 0x0c, 0x53, 0xd1, 0xf4, 0xbe, 0x8e, 0x0e, 0x28, 0xfb, 0x30, 0x74, 0xea, - 0xc7, 0x44, 0xfa, 0x09, 0x5a, 0x67, 0xe8, 0xf4, 0xf1, 0x95, 0x0c, 0xf6, - 0x22, 0xb9, 0x3d, 0xe7, 0xbd, 0xcb, 0x1a, 0x73, 0x85, 0xaf, 0xfd, 0xb4, - 0x68, 0xfd, 0x34, 0xca, 0x45, 0x69, 0x66, 0x7e, 0xea, 0xeb, 0x57, 0xc7, - 0xe9, 0xbb, 0xec, 0x33, 0x00, 0xf1, 0xd9, 0x93, 0xa6, 0xdf, 0x03, 0xd3, - 0xef, 0xb7, 0x09, 0x72, 0x65, 0xb9, 0x6e, 0xec, 0x64, 0x30, 0xad, 0x79, - 0xb9, 0x90, 0xea, 0xe5, 0xba, 0x14, 0xdb, 0x85, 0xcb, 0x0c, 0x98, 0x72, - 0x27, 0x61, 0x6f, 0x5d, 0x8a, 0x7b, 0x42, 0xc7, 0x03, 0x89, 0xae, 0xd5, - 0x23, 0x8f, 0x2f, 0x28, 0x7a, 0x67, 0x5d, 0xca, 0x57, 0x5e, 0x3a, 0xe8, - 0xa2, 0x26, 0x4a, 0xbc, 0x8e, 0xbf, 0x19, 0x03, 0xca, 0xd0, 0x18, 0xd4, - 0x1e, 0x0f, 0xa4, 0xf0, 0x4c, 0x4e, 0xef, 0xe5, 0x3a, 0xfb, 0xc4, 0x98, - 0x18, 0xd3, 0xf2, 0xcc, 0x30, 0xb0, 0xb9, 0x2e, 0x30, 0x84, 0x40, 0x5f, - 0xf8, 0x92, 0xeb, 0x91, 0x36, 0x40, 0x72, 0xd0, 0xe8, 0x8b, 0x0d, 0x01, - 0xba, 0x32, 0xa8, 0x29, 0x8e, 0x61, 0x50, 0xa7, 0x6b, 0xef, 0x44, 0xc3, - 0xdb, 0x52, 0x96, 0x9b, 0xbd, 0x7f, 0xf2, 0x4a, 0x03, 0xf3, 0x89, 0x46, - 0x2c, 0xe7, 0x5d, 0x08, 0x30, 0x4f, 0xee, 0xb1, 0x40, 0xc9, 0x12, 0x23, - 0xef, 0x75, 0x20, 0x13, 0xd9, 0xa3, 0x62, 0xde, 0xf4, 0x9d, 0x17, 0xba, - 0x0b, 0x2e, 0x28, 0xc1, 0xd4, 0x62, 0x92, 0xef, 0xcb, 0x1c, 0x61, 0xc6, - 0xb7, 0x49, 0x63, 0xee, 0x2f, 0x02, 0xa6, 0x46, 0x57, 0xa2, 0xc4, 0xba, - 0x04, 0xf4, 0x7f, 0xce, 0xc9, 0xde, 0x4b, 0xe9, 0x98, 0x75, 0x54, 0xef, - 0x0f, 0xd4, 0xec, 0x59, 0xbc, 0x9c, 0x5d, 0xca, 0xe6, 0x4e, 0xae, 0x61, - 0x69, 0xc5, 0xb0, 0x7f, 0x41, 0x27, 0x28, 0x8c, 0xdb, 0x37, 0x38, 0x41, - 0x17, 0x9c, 0xa0, 0x13, 0x4e, 0xd0, 0xbc, 0x63, 0x43, 0x5b, 0x7c, 0x7b, - 0x48, 0x77, 0x27, 0xaf, 0x7c, 0xbe, 0x7f, 0x82, 0xec, 0x6e, 0x82, 0xce, - 0x77, 0x13, 0x24, 0x65, 0x82, 0x02, 0x98, 0xb2, 0x22, 0x23, 0x36, 0xf4, - 0x40, 0x9b, 0xb2, 0x8c, 0x93, 0x61, 0xe6, 0x52, 0x1c, 0x2c, 0x36, 0x89, - 0xf3, 0x85, 0x5f, 0x5e, 0x70, 0xbd, 0x74, 0xc0, 0xb8, 0xe7, 0x70, 0x22, - 0xb7, 0x77, 0xf2, 0x4c, 0xa9, 0xde, 0x70, 0x75, 0xf5, 0x09, 0xf5, 0xc2, - 0xc1, 0xea, 0x9b, 0x71, 0x39, 0x4f, 0x59, 0x3a, 0x16, 0x0f, 0x1d, 0xe8, - 0xdd, 0xaa, 0xb2, 0x8f, 0x5f, 0x7a, 0xa9, 0x0c, 0xcf, 0xa2, 0xbb, 0xcf, - 0x4d, 0x0e, 0xf7, 0x53, 0x40, 0xc1, 0xc9, 0xf6, 0x4a, 0x9e, 0x48, 0xe1, - 0x91, 0xec, 0xd2, 0x48, 0x93, 0x7a, 0xfa, 0x5f, 0x63, 0x87, 0xff, 0xaa, - 0xc4, 0x75, 0xd4, 0x45, 0xbc, 0xdd, 0x2b, 0xab, 0x70, 0xcf, 0x0f, 0x17, - 0x7d, 0x56, 0x1f, 0x8c, 0x17, 0x1d, 0xc1, 0x8f, 0x0a, 0x11, 0xce, 0xf6, - 0xfa, 0x51, 0xf5, 0xc5, 0xe6, 0x49, 0xd7, 0xa8, 0xde, 0xca, 0x69, 0xc6, - 0xd4, 0xde, 0x0e, 0x25, 0xaa, 0x38, 0xfc, 0x31, 0xbc, 0xcf, 0x2f, 0x1e, - 0x76, 0x4b, 0x92, 0xa6, 0x85, 0x4d, 0xbb, 0xdd, 0x66, 0xdf, 0x53, 0xa4, - 0xe5, 0x6e, 0x81, 0xf3, 0xa9, 0x71, 0x5d, 0xe3, 0xf3, 0x93, 0xb7, 0x31, - 0xe8, 0x01, 0xf0, 0xef, 0x96, 0xdb, 0x27, 0xae, 0x01, 0xfc, 0x39, 0x6b, - 0xba, 0xae, 0x26, 0x15, 0x64, 0xfb, 0xa5, 0x53, 0x8d, 0x3b, 0x95, 0xd4, - 0xc7, 0x9c, 0x4b, 0x79, 0x99, 0xcc, 0x99, 0xb2, 0x28, 0x8b, 0x64, 0x4e, - 0x37, 0x27, 0x73, 0xa6, 0x0c, 0xcc, 0x98, 0x90, 0x09, 0x9a, 0x3b, 0x01, - 0xbb, 0x82, 0x57, 0xc7, 0xec, 0x4d, 0xd2, 0x5d, 0x0a, 0x4c, 0x17, 0xd0, - 0xa3, 0xe5, 0x55, 0xa6, 0x7a, 0xf4, 0x66, 0x88, 0x3d, 0x3d, 0x06, 0x58, - 0xac, 0x93, 0x34, 0x66, 0x6f, 0xba, 0x5d, 0xf6, 0x26, 0xcd, 0xef, 0x9d, - 0xb2, 0x37, 0xf0, 0xd5, 0x0f, 0xb3, 0x37, 0xcd, 0x2e, 0x7b, 0xa3, 0x19, - 0xa2, 0x57, 0xf5, 0xd9, 0xb7, 0x7e, 0xa2, 0x06, 0x27, 0x40, 0x19, 0x74, - 0x12, 0x34, 0x5a, 0x82, 0x59, 0xbf, 0xc1, 0x20, 0x53, 0x06, 0xb6, 0xba, - 0x8d, 0x2f, 0x10, 0x89, 0xab, 0x2d, 0x0d, 0xb0, 0x8f, 0xd2, 0x07, 0xe0, - 0x10, 0x0c, 0x4c, 0xc7, 0x3d, 0x51, 0xaa, 0x17, 0x9b, 0x22, 0x15, 0x25, - 0xa4, 0x55, 0xa2, 0x23, 0xfa, 0x73, 0x61, 0xc9, 0xfe, 0x9f, 0xea, 0x67, - 0x8e, 0xe6, 0x1b, 0x8a, 0x64, 0xbd, 0x54, 0x24, 0xff, 0x70, 0x2d, 0xf1, - 0x81, 0x03, 0x3d, 0x8c, 0x37, 0x6d, 0x30, 0x2c, 0xe0, 0xed, 0x5e, 0xba, - 0xf5, 0x5d, 0x1b, 0xfc, 0x23, 0x4e, 0x76, 0x90, 0x85, 0x28, 0x7a, 0xb4, - 0xc1, 0x8b, 0xb4, 0xee, 0x3e, 0x48, 0xaa, 0xa2, 0xbb, 0x03, 0x76, 0x0e, - 0x43, 0xd8, 0xca, 0xfa, 0x09, 0x26, 0x6d, 0x04, 0x84, 0x27, 0xe4, 0xe2, - 0xed, 0x88, 0x15, 0xfb, 0x8f, 0x83, 0xe8, 0x1f, 0x78, 0x29, 0xee, 0x20, - 0xab, 0x55, 0xe4, 0xac, 0xfe, 0xee, 0x73, 0x31, 0x5f, 0x37, 0xcf, 0x30, - 0x64, 0xa7, 0x19, 0xc4, 0x43, 0x43, 0xbc, 0x0d, 0xc5, 0xe7, 0x85, 0xd6, - 0x15, 0x03, 0xfe, 0xeb, 0x3b, 0xb9, 0x1f, 0x82, 0x42, 0xa9, 0x09, 0x57, - 0xad, 0xcb, 0xfa, 0x28, 0x2f, 0xaf, 0x4e, 0xd4, 0xcf, 0x80, 0x79, 0xaf, - 0x4e, 0x14, 0x28, 0x78, 0x18, 0xdc, 0x73, 0x81, 0xa0, 0x1b, 0xae, 0xfe, - 0x7d, 0x22, 0xa1, 0x00, 0xa7, 0xe7, 0x8c, 0xc7, 0x7f, 0x04, 0x41, 0x03, - 0x49, 0x71, 0x9a, 0x37, 0x8c, 0x01, 0x04, 0x2a, 0xa3, 0x2c, 0xc9, 0xa9, - 0xfa, 0xf9, 0x86, 0x2d, 0x34, 0xdf, 0xf1, 0x93, 0x19, 0x65, 0xa2, 0xb8, - 0x38, 0x45, 0x26, 0x4e, 0xd4, 0x71, 0x60, 0x72, 0xc1, 0xa9, 0x4c, 0xbc, - 0xb7, 0xad, 0x98, 0xeb, 0x55, 0xa7, 0x1d, 0xc3, 0xf3, 0xb6, 0x62, 0x2b, - 0x9a, 0x3e, 0xf0, 0x83, 0x86, 0x4e, 0x4b, 0x3e, 0xe1, 0xb5, 0x6d, 0xc5, - 0xd5, 0x72, 0x5b, 0xb1, 0x79, 0x6d, 0x5b, 0xf1, 0xbd, 0xe6, 0x8a, 0xc6, - 0x6d, 0xc5, 0x5d, 0xd9, 0x56, 0xac, 0x29, 0xa6, 0x69, 0x3f, 0x18, 0x63, - 0xbd, 0x2f, 0x0b, 0xf2, 0x5f, 0x5e, 0x16, 0xfd, 0xeb, 0xf7, 0xfd, 0xe0, - 0xa2, 0xc3, 0xc0, 0x72, 0x55, 0x34, 0x31, 0x32, 0x0b, 0x5d, 0x1a, 0x6d, - 0x88, 0x87, 0xbf, 0xcb, 0x3b, 0xfc, 0x49, 0x97, 0xf6, 0xc4, 0x5a, 0x17, - 0xed, 0x17, 0x27, 0xf3, 0xf6, 0x01, 0xb8, 0x39, 0xd0, 0xd9, 0xba, 0x49, - 0x10, 0xdd, 0x26, 0xbb, 0xfe, 0xaf, 0xc6, 0xec, 0x65, 0xf7, 0xf6, 0x37, - 0x80, 0x84, 0x71, 0xcf, 0x90, 0xc1, 0x9d, 0x70, 0xd5, 0x18, 0x8b, 0x00, - 0xb4, 0x75, 0x57, 0x99, 0xc1, 0xd7, 0x70, 0x92, 0x6c, 0x1f, 0xb8, 0x39, - 0xc7, 0x1f, 0xe5, 0x26, 0xfa, 0xf3, 0xcc, 0xf8, 0xbd, 0x30, 0x76, 0x91, - 0xab, 0xc1, 0x75, 0xfe, 0x02, 0x20, 0x21, 0x30, 0x78, 0xcf, 0x7d, 0x02, - 0x03, 0x18, 0x42, 0x63, 0xcf, 0x26, 0xfb, 0xd6, 0x5d, 0xc6, 0x7a, 0x60, - 0x64, 0xb6, 0xb3, 0xf7, 0x30, 0x50, 0x2b, 0xe3, 0x36, 0x5d, 0xfd, 0x84, - 0x71, 0x0e, 0xc6, 0xde, 0xf6, 0x8c, 0x9a, 0x78, 0x69, 0x1b, 0x99, 0xf6, - 0xaf, 0x33, 0xb0, 0xe2, 0xb3, 0x46, 0xec, 0x19, 0xba, 0x2d, 0xb9, 0x2b, - 0x9f, 0x34, 0x5e, 0xab, 0xe1, 0x7a, 0x1a, 0xba, 0x8e, 0xc6, 0x2d, 0x36, - 0x49, 0x57, 0x0c, 0xe8, 0x76, 0xe9, 0xce, 0x6f, 0x3b, 0x1f, 0xed, 0x4d, - 0xb4, 0x43, 0xfd, 0x48, 0x29, 0xcc, 0xfa, 0xe3, 0xa9, 0xfe, 0x98, 0x6c, - 0xae, 0x1f, 0x33, 0xb8, 0x38, 0xfb, 0x23, 0x30, 0xd1, 0x1a, 0x78, 0xc1, - 0x5d, 0x24, 0xf7, 0xf7, 0x26, 0xe6, 0xe6, 0xf6, 0x68, 0xf0, 0x47, 0x4f, - 0x7d, 0xb0, 0xfd, 0x6a, 0xc0, 0x8f, 0xfe, 0x0c, 0x3f, 0xda, 0xcd, 0x39, - 0xea, 0xf7, 0x31, 0x34, 0x71, 0x18, 0x1c, 0x6e, 0x70, 0xe8, 0xbc, 0xbd, - 0xc4, 0x23, 0x17, 0x77, 0x29, 0x37, 0x77, 0x69, 0xe5, 0x8f, 0x86, 0x95, - 0x43, 0x3b, 0xee, 0xe4, 0x3a, 0xd9, 0xcb, 0xab, 0x94, 0xeb, 0xbb, 0xf4, - 0xc9, 0x9b, 0xbc, 0xb2, 0x6b, 0xbc, 0xf4, 0xf8, 0x1e, 0x2f, 0xed, 0x86, - 0xa1, 0x7e, 0x8a, 0x1e, 0x3f, 0x0e, 0x16, 0xb4, 0x9d, 0xd5, 0x0f, 0xb1, - 0xb9, 0xed, 0x9e, 0x87, 0xea, 0x29, 0xba, 0x95, 0x59, 0x0d, 0x20, 0xc7, - 0xfd, 0xbd, 0xc4, 0xcc, 0x03, 0x26, 0xb8, 0x47, 0x57, 0x43, 0xe2, 0x8f, - 0xb9, 0x84, 0xcd, 0x21, 0x81, 0x98, 0x60, 0x8c, 0x4e, 0xac, 0x75, 0xbd, - 0xbb, 0x46, 0xcb, 0x7d, 0x3c, 0xfc, 0x11, 0xfd, 0x67, 0x8c, 0x94, 0x9c, - 0xab, 0x1b, 0xbb, 0x95, 0x8d, 0xf9, 0x63, 0xcf, 0x91, 0xa2, 0x43, 0xe3, - 0x3b, 0xcc, 0x09, 0x77, 0x5c, 0x61, 0xd6, 0x18, 0x80, 0xf2, 0x1a, 0x3a, - 0x8f, 0x98, 0x5e, 0x66, 0x0f, 0x02, 0x43, 0xc6, 0x4d, 0xca, 0x5c, 0x4e, - 0x4c, 0x37, 0x88, 0xa1, 0xf3, 0xe7, 0x97, 0xa1, 0x73, 0x53, 0x36, 0x80, - 0xcd, 0x31, 0x73, 0x5f, 0x56, 0xd1, 0x71, 0xed, 0xdc, 0x6e, 0x23, 0xcb, - 0x32, 0x11, 0xd9, 0x8e, 0x8f, 0x93, 0xd9, 0x3c, 0x30, 0xa9, 0xc6, 0xcc, - 0x4b, 0x8c, 0xde, 0xf5, 0x8c, 0xd8, 0x33, 0x66, 0xde, 0x4b, 0x35, 0x46, - 0xf3, 0x87, 0x66, 0x0a, 0xf1, 0xe3, 0x70, 0x33, 0x05, 0xcb, 0x4b, 0x62, - 0xa6, 0x24, 0x04, 0xa6, 0x2c, 0x57, 0xb9, 0xb0, 0x3b, 0xf8, 0x9b, 0x5d, - 0x7a, 0x60, 0xef, 0x90, 0xf6, 0x93, 0x05, 0xe5, 0x10, 0xf9, 0x77, 0x1a, - 0xc6, 0xc3, 0x98, 0x3a, 0x00, 0xd3, 0x62, 0xce, 0x35, 0x83, 0xb0, 0x38, - 0xac, 0x3b, 0xf0, 0x91, 0x01, 0x03, 0xed, 0x1d, 0xda, 0xea, 0x11, 0xbd, - 0xc2, 0xe1, 0x19, 0x87, 0x6d, 0x39, 0xec, 0x65, 0x60, 0xa7, 0xc3, 0xcb, - 0x4d, 0x3e, 0x73, 0x92, 0xa1, 0x21, 0xc7, 0x6b, 0x7e, 0x62, 0x4e, 0x29, - 0x70, 0x43, 0x82, 0xee, 0xb2, 0x0b, 0xb4, 0x26, 0x5b, 0xea, 0xba, 0x07, - 0x0a, 0xf1, 0x33, 0x17, 0xfa, 0x08, 0x0d, 0x2a, 0x26, 0x18, 0xf7, 0xeb, - 0x09, 0x5d, 0x0d, 0x9e, 0x00, 0xd8, 0x73, 0xea, 0xcb, 0x65, 0x3d, 0x79, - 0xff, 0xde, 0xa2, 0xe0, 0x96, 0xf7, 0x76, 0x2f, 0xee, 0x7d, 0x01, 0xc7, - 0xb9, 0x11, 0xb8, 0xa6, 0x06, 0x74, 0x0c, 0x1f, 0x38, 0x2a, 0x44, 0x4f, - 0x4b, 0x44, 0x47, 0x86, 0x4d, 0x0f, 0x1f, 0x2b, 0x8a, 0x5a, 0x65, 0x61, - 0x07, 0x6e, 0x33, 0x01, 0xb8, 0x27, 0x33, 0x83, 0xcd, 0x7b, 0xd6, 0xb8, - 0xf5, 0xc4, 0xce, 0xb7, 0x7c, 0xb4, 0xd1, 0x7a, 0xec, 0x5c, 0xa1, 0x25, - 0xd5, 0x23, 0x91, 0x96, 0xb1, 0xda, 0x5a, 0x53, 0x2c, 0x3f, 0xe1, 0xc3, - 0x9d, 0x8b, 0x49, 0x45, 0xd4, 0x02, 0x27, 0x45, 0xee, 0x8a, 0xe9, 0xbe, - 0xd1, 0x8c, 0x3b, 0x52, 0xc9, 0x2d, 0x2b, 0x6d, 0x88, 0x0d, 0x47, 0xd3, - 0xe9, 0x8a, 0x29, 0x2e, 0xa0, 0x52, 0xb8, 0xfb, 0x0d, 0x90, 0x00, 0x1a, - 0x6f, 0x28, 0x74, 0xb1, 0x59, 0x28, 0x96, 0x58, 0x97, 0xed, 0x42, 0xff, - 0x66, 0x3e, 0x9b, 0xa6, 0x0f, 0xdc, 0x7d, 0x09, 0x2b, 0xec, 0x18, 0x3a, - 0x16, 0x5d, 0x7b, 0xa2, 0x30, 0x94, 0x99, 0x62, 0x9a, 0x68, 0xe0, 0x1f, - 0x5c, 0xa6, 0x46, 0xfa, 0xd7, 0xb2, 0x11, 0xe2, 0x6f, 0xe3, 0xf6, 0x50, - 0x5d, 0xa1, 0xc6, 0x2c, 0x08, 0x58, 0x9e, 0xe6, 0x88, 0x48, 0x95, 0x68, - 0x2a, 0x37, 0xba, 0xe2, 0x8f, 0x5e, 0xa3, 0x1d, 0x1d, 0x45, 0xba, 0xa9, - 0xea, 0x2c, 0x9e, 0x80, 0x20, 0xe6, 0x4e, 0x41, 0x03, 0x3c, 0x5b, 0x98, - 0x88, 0xce, 0xd2, 0x8e, 0xe2, 0x32, 0x1c, 0x5e, 0x13, 0x16, 0x97, 0x45, - 0xc3, 0x9d, 0xcc, 0x8d, 0xb1, 0xfd, 0xac, 0x7f, 0x2b, 0xe4, 0x20, 0x5b, - 0xd4, 0x1c, 0x5c, 0x0e, 0x92, 0xc6, 0xcb, 0xef, 0x35, 0x7e, 0x70, 0x79, - 0x24, 0xad, 0x82, 0xfd, 0x52, 0xf7, 0x96, 0xb9, 0x34, 0x6e, 0x07, 0xa1, - 0xeb, 0xcd, 0xe5, 0x61, 0xad, 0x28, 0x34, 0xa6, 0xb1, 0x8d, 0xd3, 0x2e, - 0x86, 0xf2, 0x97, 0x1d, 0xda, 0xff, 0xbf, 0x63, 0x61, 0xbf, 0x72, 0x2c, - 0xf8, 0x87, 0x58, 0x14, 0x07, 0x96, 0xd5, 0x03, 0x41, 0xa1, 0x08, 0x30, - 0xb6, 0x3e, 0x75, 0x2c, 0x63, 0xdc, 0xa0, 0x53, 0x12, 0x2e, 0x35, 0x09, - 0x42, 0x5c, 0xc0, 0x7c, 0x3e, 0xf3, 0x94, 0x42, 0x4a, 0x40, 0xc5, 0x9d, - 0xe8, 0xc2, 0x02, 0xb1, 0x71, 0x8e, 0x93, 0x54, 0xe3, 0x5f, 0x07, 0x51, - 0x68, 0xdb, 0x99, 0x79, 0xbb, 0x6e, 0x89, 0xa4, 0xf8, 0x12, 0x51, 0x23, - 0xd7, 0xae, 0x0b, 0xc3, 0xf2, 0xb4, 0x5f, 0xc6, 0x5a, 0xc2, 0xd8, 0xc6, - 0x30, 0xb7, 0x31, 0x6d, 0x71, 0x7e, 0xfd, 0x74, 0xf1, 0x2c, 0xaf, 0xb0, - 0x3a, 0xfe, 0xaa, 0x7b, 0x38, 0x55, 0x17, 0x33, 0x30, 0x4c, 0x98, 0xff, - 0xbc, 0x38, 0xfd, 0x70, 0xf6, 0x36, 0xfc, 0x92, 0xec, 0x6d, 0x53, 0x16, - 0xd0, 0x4d, 0x7b, 0x76, 0xb8, 0xb4, 0xac, 0x7f, 0x23, 0xff, 0x3a, 0x5d, - 0x16, 0x75, 0x51, 0xf9, 0x57, 0x88, 0xe4, 0x1b, 0xb3, 0xb7, 0xff, 0x07, - 0xcb, 0x4b, 0x74, 0x5c, 0x80, 0x4a, 0x00, 0x00 -}; +const uint8_t Antonio_SemiBold40pt7bBitmaps[] PROGMEM = { + 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF9, 0xFE, 0x7F, + 0x9F, 0xE7, 0xF9, 0xFE, 0x7F, 0x9F, 0xE7, 0xF9, 0xFE, 0x7F, 0x9F, 0xE7, + 0xF9, 0xFE, 0x7F, 0x9F, 0xE7, 0xF8, 0xFC, 0x3F, 0x0F, 0xC3, 0xF0, 0xFC, + 0x3F, 0x0F, 0xC3, 0xF0, 0xFC, 0x3F, 0x0F, 0xC3, 0xF0, 0xFC, 0x3F, 0x0F, + 0xC3, 0xF0, 0xFC, 0x1E, 0x07, 0x81, 0xE0, 0x78, 0x1E, 0x07, 0x81, 0xE0, + 0x78, 0x1E, 0x07, 0x81, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x0F, 0xFB, 0xFE, 0xFF, 0xBF, 0xEF, 0xFB, 0xFE, 0xFF, 0xBF, 0xEF, + 0xF8, 0xFF, 0xFF, 0xEF, 0xFB, 0xFE, 0xFF, 0xBF, 0xEF, 0xFB, 0xFE, 0xFF, + 0x1F, 0xC7, 0xF1, 0xFC, 0x7F, 0x1F, 0xC7, 0xF1, 0xF8, 0x7E, 0x1F, 0x87, + 0xE1, 0xF8, 0x7E, 0x1F, 0x87, 0xC1, 0xF0, 0x7C, 0x00, 0x00, 0x07, 0xE0, + 0x3F, 0x80, 0x01, 0xF8, 0x0F, 0xC0, 0x00, 0xFE, 0x03, 0xF0, 0x00, 0x3F, + 0x81, 0xFC, 0x00, 0x0F, 0xE0, 0x7F, 0x00, 0x03, 0xF0, 0x1F, 0xC0, 0x00, + 0xFC, 0x07, 0xF0, 0x00, 0x3F, 0x01, 0xF8, 0x00, 0x1F, 0xC0, 0x7E, 0x00, + 0x07, 0xF0, 0x3F, 0x80, 0x01, 0xFC, 0x0F, 0xE0, 0x00, 0x7E, 0x03, 0xF8, + 0x00, 0x1F, 0x80, 0xFE, 0x00, 0x07, 0xE0, 0x3F, 0x00, 0x03, 0xF8, 0x0F, + 0xC0, 0x00, 0xFE, 0x07, 0xF0, 0x00, 0x3F, 0x81, 0xFC, 0x00, 0x0F, 0xC0, + 0x7F, 0x00, 0x03, 0xF0, 0x1F, 0xC0, 0x00, 0xFC, 0x07, 0xE0, 0x00, 0x7F, + 0x01, 0xF8, 0x00, 0x1F, 0xC0, 0xFE, 0x03, 0xFF, 0xFF, 0xFF, 0xFC, 0xFF, + 0xFF, 0xFF, 0xFF, 0x3F, 0xFF, 0xFF, 0xFF, 0xCF, 0xFF, 0xFF, 0xFF, 0xF3, + 0xFF, 0xFF, 0xFF, 0xFC, 0x03, 0xF8, 0x1F, 0xC0, 0x00, 0xFE, 0x07, 0xF0, + 0x00, 0x3F, 0x01, 0xFC, 0x00, 0x0F, 0xC0, 0x7F, 0x00, 0x03, 0xF0, 0x1F, + 0x80, 0x01, 0xFC, 0x07, 0xE0, 0x00, 0x7F, 0x01, 0xF8, 0x00, 0x1F, 0xC0, + 0xFE, 0x00, 0x07, 0xE0, 0x3F, 0x80, 0x01, 0xF8, 0x0F, 0xE0, 0x00, 0x7E, + 0x03, 0xF0, 0x00, 0x3F, 0x80, 0xFC, 0x03, 0xFF, 0xFF, 0xFF, 0xFC, 0xFF, + 0xFF, 0xFF, 0xFF, 0x3F, 0xFF, 0xFF, 0xFF, 0xCF, 0xFF, 0xFF, 0xFF, 0xF3, + 0xFF, 0xFF, 0xFF, 0xFC, 0x07, 0xF0, 0x1F, 0x80, 0x01, 0xFC, 0x07, 0xE0, + 0x00, 0x7F, 0x03, 0xF8, 0x00, 0x1F, 0x80, 0xFE, 0x00, 0x07, 0xE0, 0x3F, + 0x80, 0x01, 0xF8, 0x0F, 0xC0, 0x00, 0xFE, 0x03, 0xF0, 0x00, 0x3F, 0x80, + 0xFC, 0x00, 0x0F, 0xE0, 0x7F, 0x00, 0x03, 0xF8, 0x1F, 0xC0, 0x00, 0xFC, + 0x07, 0xF0, 0x00, 0x3F, 0x01, 0xFC, 0x00, 0x1F, 0xC0, 0x7E, 0x00, 0x07, + 0xF0, 0x1F, 0x80, 0x01, 0xFC, 0x0F, 0xE0, 0x00, 0x7F, 0x03, 0xF8, 0x00, + 0x1F, 0x80, 0xFE, 0x00, 0x07, 0xE0, 0x3F, 0x80, 0x01, 0xF8, 0x0F, 0xC0, + 0x00, 0xFE, 0x03, 0xF0, 0x00, 0x3F, 0x81, 0xFC, 0x00, 0x0F, 0xE0, 0x7F, + 0x00, 0x03, 0xF0, 0x1F, 0xC0, 0x00, 0x00, 0x1F, 0x00, 0x00, 0x07, 0xC0, + 0x00, 0x01, 0xF0, 0x00, 0x00, 0x7C, 0x00, 0x00, 0x1F, 0x00, 0x00, 0x07, + 0xC0, 0x00, 0x01, 0xF0, 0x00, 0x00, 0x7C, 0x00, 0x00, 0x1F, 0x00, 0x00, + 0x7F, 0xF8, 0x00, 0x7F, 0xFF, 0x80, 0x3F, 0xFF, 0xF0, 0x1F, 0xFF, 0xFC, + 0x0F, 0xFF, 0xFF, 0x83, 0xFF, 0xFF, 0xF1, 0xFF, 0xFF, 0xFC, 0x7F, 0xC1, + 0xFF, 0x1F, 0xF0, 0x3F, 0xEF, 0xF8, 0x0F, 0xFB, 0xFE, 0x01, 0xFE, 0xFF, + 0x80, 0x7F, 0xBF, 0xE0, 0x1F, 0xEF, 0xF8, 0x07, 0xFB, 0xFE, 0x01, 0xFE, + 0xFF, 0x80, 0x7F, 0x9F, 0xE0, 0x1F, 0xE7, 0xFC, 0x07, 0xF9, 0xFF, 0x01, + 0xFE, 0x7F, 0xE0, 0x7F, 0x8F, 0xFC, 0x00, 0x03, 0xFF, 0x00, 0x00, 0x7F, + 0xE0, 0x00, 0x1F, 0xFE, 0x00, 0x03, 0xFF, 0xC0, 0x00, 0x7F, 0xF8, 0x00, + 0x1F, 0xFF, 0x00, 0x03, 0xFF, 0xE0, 0x00, 0x7F, 0xFC, 0x00, 0x0F, 0xFF, + 0x80, 0x00, 0xFF, 0xF0, 0x00, 0x1F, 0xFC, 0x00, 0x03, 0xFF, 0x80, 0x00, + 0x7F, 0xF0, 0x00, 0x0F, 0xFC, 0x00, 0x01, 0xFF, 0x80, 0x00, 0x7F, 0xE7, + 0xF8, 0x0F, 0xF9, 0xFE, 0x03, 0xFF, 0x7F, 0x80, 0x7F, 0xDF, 0xE0, 0x1F, + 0xF7, 0xF8, 0x07, 0xFD, 0xFE, 0x01, 0xFF, 0x7F, 0x80, 0x3F, 0xDF, 0xE0, + 0x0F, 0xF7, 0xF8, 0x03, 0xFD, 0xFE, 0x01, 0xFF, 0x7F, 0xC0, 0x7F, 0xDF, + 0xF0, 0x1F, 0xF7, 0xFE, 0x0F, 0xFC, 0xFF, 0xC7, 0xFE, 0x3F, 0xFF, 0xFF, + 0x87, 0xFF, 0xFF, 0xE1, 0xFF, 0xFF, 0xF0, 0x3F, 0xFF, 0xF8, 0x07, 0xFF, + 0xFC, 0x00, 0xFF, 0xFE, 0x00, 0x07, 0xFC, 0x00, 0x00, 0x3C, 0x00, 0x00, + 0x0F, 0x00, 0x00, 0x03, 0xC0, 0x00, 0x00, 0xF0, 0x00, 0x00, 0x3C, 0x00, + 0x00, 0x0F, 0x00, 0x00, 0x03, 0xC0, 0x00, 0x00, 0xF0, 0x00, 0x00, 0x3C, + 0x00, 0x01, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xFF, + 0xE0, 0x00, 0x00, 0x07, 0xF8, 0x00, 0x00, 0x1F, 0xFF, 0xF8, 0x00, 0x00, + 0x07, 0xF0, 0x00, 0x00, 0x3F, 0xFF, 0xFC, 0x00, 0x00, 0x07, 0xF0, 0x00, + 0x00, 0x3F, 0xFF, 0xFC, 0x00, 0x00, 0x0F, 0xE0, 0x00, 0x00, 0x7F, 0xFF, + 0xFE, 0x00, 0x00, 0x0F, 0xE0, 0x00, 0x00, 0x7F, 0xF7, 0xFE, 0x00, 0x00, + 0x0F, 0xE0, 0x00, 0x00, 0x7F, 0x81, 0xFF, 0x00, 0x00, 0x1F, 0xC0, 0x00, + 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x1F, 0xC0, 0x00, 0x00, 0xFF, 0x00, + 0xFF, 0x00, 0x00, 0x3F, 0x80, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, + 0x3F, 0x80, 0x00, 0x00, 0xFF, 0x00, 0x7F, 0x00, 0x00, 0x3F, 0x80, 0x00, + 0x00, 0xFF, 0x00, 0x7F, 0x00, 0x00, 0x7F, 0x00, 0x00, 0x00, 0xFF, 0x00, + 0x7F, 0x00, 0x00, 0x7F, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x7F, 0x00, 0x00, + 0xFE, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x7F, 0x00, 0x00, 0xFE, 0x00, 0x00, + 0x00, 0xFF, 0x00, 0x7F, 0x00, 0x00, 0xFE, 0x00, 0x00, 0x00, 0xFF, 0x00, + 0x7F, 0x00, 0x01, 0xFC, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x7F, 0x00, 0x01, + 0xFC, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x7F, 0x00, 0x03, 0xFC, 0x00, 0x00, + 0x00, 0xFF, 0x00, 0x7F, 0x00, 0x03, 0xF8, 0x00, 0x00, 0x00, 0xFF, 0x00, + 0x7F, 0x00, 0x03, 0xF8, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x7F, 0x00, 0x07, + 0xF0, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x7F, 0x00, 0x07, 0xF0, 0x03, 0xFF, + 0x80, 0xFF, 0x00, 0x7F, 0x00, 0x0F, 0xF0, 0x0F, 0xFF, 0xE0, 0xFF, 0x00, + 0x7F, 0x00, 0x0F, 0xE0, 0x1F, 0xFF, 0xF0, 0xFF, 0x00, 0x7F, 0x00, 0x0F, + 0xE0, 0x3F, 0xFF, 0xF8, 0xFF, 0x00, 0x7F, 0x00, 0x1F, 0xC0, 0x7F, 0xFF, + 0xFC, 0xFF, 0x00, 0x7F, 0x00, 0x1F, 0xC0, 0x7F, 0xFF, 0xFC, 0xFF, 0x00, + 0x7F, 0x00, 0x3F, 0xC0, 0xFF, 0xEF, 0xFE, 0xFF, 0x00, 0x7F, 0x00, 0x3F, + 0x80, 0xFF, 0x01, 0xFE, 0xFF, 0x00, 0x7F, 0x00, 0x3F, 0x80, 0xFF, 0x01, + 0xFE, 0xFF, 0x00, 0x7F, 0x00, 0x7F, 0x00, 0xFE, 0x00, 0xFE, 0xFF, 0x00, + 0x7F, 0x00, 0x7F, 0x01, 0xFE, 0x00, 0xFE, 0xFF, 0x00, 0x7F, 0x00, 0xFF, + 0x01, 0xFE, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0x00, 0xFE, 0x01, 0xFE, 0x00, + 0xFF, 0xFF, 0x00, 0xFF, 0x00, 0xFE, 0x01, 0xFE, 0x00, 0xFF, 0x7F, 0x00, + 0xFF, 0x01, 0xFC, 0x01, 0xFE, 0x00, 0xFF, 0x7F, 0x81, 0xFE, 0x01, 0xFC, + 0x01, 0xFE, 0x00, 0xFF, 0x7F, 0xFF, 0xFE, 0x03, 0xFC, 0x01, 0xFE, 0x00, + 0xFF, 0x3F, 0xFF, 0xFE, 0x03, 0xF8, 0x01, 0xFE, 0x00, 0xFF, 0x3F, 0xFF, + 0xFC, 0x03, 0xF8, 0x01, 0xFE, 0x00, 0xFF, 0x1F, 0xFF, 0xF8, 0x07, 0xF0, + 0x01, 0xFE, 0x00, 0xFF, 0x0F, 0xFF, 0xF0, 0x07, 0xF0, 0x01, 0xFE, 0x00, + 0xFF, 0x03, 0xFF, 0xE0, 0x0F, 0xF0, 0x01, 0xFE, 0x00, 0xFF, 0x00, 0x7F, + 0x00, 0x0F, 0xE0, 0x01, 0xFE, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x0F, 0xE0, + 0x01, 0xFE, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x1F, 0xE0, 0x01, 0xFE, 0x00, + 0xFF, 0x00, 0x00, 0x00, 0x1F, 0xC0, 0x01, 0xFE, 0x00, 0xFF, 0x00, 0x00, + 0x00, 0x3F, 0xC0, 0x01, 0xFE, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x3F, 0x80, + 0x01, 0xFE, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x3F, 0x80, 0x01, 0xFE, 0x00, + 0xFF, 0x00, 0x00, 0x00, 0x7F, 0x80, 0x01, 0xFE, 0x00, 0xFF, 0x00, 0x00, + 0x00, 0x7F, 0x00, 0x01, 0xFE, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, + 0x01, 0xFE, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFE, 0x00, 0x01, 0xFE, 0x00, + 0xFF, 0x00, 0x00, 0x00, 0xFE, 0x00, 0x01, 0xFE, 0x00, 0xFF, 0x00, 0x00, + 0x01, 0xFE, 0x00, 0x01, 0xFE, 0x00, 0xFE, 0x00, 0x00, 0x01, 0xFC, 0x00, + 0x00, 0xFE, 0x00, 0xFE, 0x00, 0x00, 0x03, 0xFC, 0x00, 0x00, 0xFE, 0x01, + 0xFE, 0x00, 0x00, 0x03, 0xF8, 0x00, 0x00, 0xFF, 0x01, 0xFE, 0x00, 0x00, + 0x03, 0xF8, 0x00, 0x00, 0xFF, 0x83, 0xFE, 0x00, 0x00, 0x07, 0xF8, 0x00, + 0x00, 0x7F, 0xFF, 0xFC, 0x00, 0x00, 0x07, 0xF0, 0x00, 0x00, 0x7F, 0xFF, + 0xFC, 0x00, 0x00, 0x0F, 0xF0, 0x00, 0x00, 0x3F, 0xFF, 0xF8, 0x00, 0x00, + 0x0F, 0xE0, 0x00, 0x00, 0x3F, 0xFF, 0xF8, 0x00, 0x00, 0x0F, 0xE0, 0x00, + 0x00, 0x1F, 0xFF, 0xF0, 0x00, 0x00, 0x1F, 0xE0, 0x00, 0x00, 0x07, 0xFF, + 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7C, 0x00, 0x00, 0x0F, + 0xF8, 0x00, 0x00, 0x07, 0xFF, 0xC0, 0x00, 0x03, 0xFF, 0xFC, 0x00, 0x00, + 0xFF, 0xFF, 0xC0, 0x00, 0x1F, 0xFF, 0xFC, 0x00, 0x07, 0xFF, 0xFF, 0x80, + 0x00, 0xFF, 0xDF, 0xF0, 0x00, 0x3F, 0xE0, 0x7F, 0x00, 0x07, 0xF8, 0x0F, + 0xE0, 0x00, 0xFF, 0x00, 0xFC, 0x00, 0x1F, 0xE0, 0x1F, 0x80, 0x03, 0xFC, + 0x03, 0xF0, 0x00, 0xFF, 0x80, 0x7E, 0x00, 0x1F, 0xF0, 0x0F, 0xC0, 0x01, + 0xFE, 0x01, 0xF8, 0x00, 0x3F, 0xC0, 0x3F, 0x00, 0x07, 0xF8, 0x0F, 0xE0, + 0x00, 0xFF, 0x01, 0xFC, 0x00, 0x1F, 0xE0, 0x3F, 0x80, 0x01, 0xFE, 0x07, + 0xF0, 0x00, 0x3F, 0xC1, 0xFC, 0x00, 0x07, 0xF8, 0x3F, 0x80, 0x00, 0x7F, + 0x8F, 0xE0, 0x00, 0x0F, 0xF3, 0xFC, 0x00, 0x01, 0xFE, 0x7F, 0x00, 0x00, + 0x1F, 0xFF, 0xE0, 0x00, 0x03, 0xFF, 0xF8, 0x00, 0x00, 0x7F, 0xFF, 0x00, + 0x00, 0x07, 0xFF, 0xC0, 0x00, 0x00, 0xFF, 0xF0, 0x00, 0x00, 0x1F, 0xFE, + 0x00, 0x00, 0x01, 0xFF, 0x80, 0x00, 0x00, 0x3F, 0xE0, 0x00, 0x00, 0x0F, + 0xFC, 0x00, 0x00, 0x03, 0xFF, 0x80, 0x00, 0x00, 0xFF, 0xF8, 0x00, 0x00, + 0x1F, 0xFF, 0x00, 0x10, 0x07, 0xFF, 0xE0, 0x06, 0x01, 0xFF, 0xFE, 0x01, + 0xC0, 0x3F, 0xFF, 0xC0, 0x3C, 0x0F, 0xF3, 0xFC, 0x0F, 0xC3, 0xFE, 0x7F, + 0x83, 0xF8, 0x7F, 0x8F, 0xF0, 0x7F, 0x9F, 0xF0, 0xFF, 0x1F, 0xE3, 0xFC, + 0x1F, 0xE3, 0xF8, 0xFF, 0x81, 0xFE, 0xFF, 0x1F, 0xE0, 0x3F, 0xFF, 0xC3, + 0xFC, 0x07, 0xFF, 0xF0, 0xFF, 0x00, 0x7F, 0xFE, 0x1F, 0xE0, 0x0F, 0xFF, + 0x83, 0xFC, 0x00, 0xFF, 0xF0, 0x7F, 0x80, 0x1F, 0xFC, 0x0F, 0xF0, 0x01, + 0xFF, 0x81, 0xFE, 0x00, 0x3F, 0xE0, 0x3F, 0xC0, 0x07, 0xFC, 0x07, 0xF8, + 0x00, 0xFF, 0x80, 0xFF, 0x00, 0x3F, 0xF0, 0x1F, 0xE0, 0x07, 0xFF, 0x03, + 0xFC, 0x01, 0xFF, 0xE0, 0x7F, 0xC0, 0x7F, 0xFE, 0x0F, 0xFC, 0x1F, 0xFF, + 0xC0, 0xFF, 0xFF, 0xFF, 0xFC, 0x1F, 0xFF, 0xFF, 0xFF, 0x81, 0xFF, 0xFF, + 0xEF, 0xF0, 0x3F, 0xFF, 0xF8, 0xFF, 0x03, 0xFF, 0xFE, 0x1F, 0xE0, 0x3F, + 0xFF, 0x81, 0xFE, 0x01, 0xFF, 0xC0, 0x3F, 0xC0, 0x07, 0xE0, 0x00, 0x00, + 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0x7F, 0x7F, 0x7F, 0x7E, 0x7E, 0x7E, 0x7E, + 0x7E, 0x7E, 0x7E, 0x3E, 0x3E, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, + 0x00, 0x7C, 0x0F, 0xF0, 0xFF, 0xC7, 0xFF, 0x3F, 0xFC, 0xFF, 0xF7, 0xFF, + 0xDF, 0xF8, 0x7F, 0xC1, 0xFE, 0x0F, 0xF8, 0x3F, 0xE0, 0xFF, 0x83, 0xFE, + 0x0F, 0xF8, 0x3F, 0xE0, 0xFF, 0x83, 0xFE, 0x0F, 0xF8, 0x3F, 0xE0, 0xFF, + 0x83, 0xFE, 0x0F, 0xF8, 0x3F, 0xE0, 0xFF, 0x83, 0xFE, 0x0F, 0xF8, 0x3F, + 0xE0, 0xFF, 0x83, 0xFE, 0x0F, 0xF8, 0x3F, 0xE0, 0xFF, 0x83, 0xFE, 0x0F, + 0xF8, 0x3F, 0xE0, 0xFF, 0x83, 0xFE, 0x0F, 0xF8, 0x3F, 0xE0, 0xFF, 0x83, + 0xFE, 0x0F, 0xF8, 0x3F, 0xE0, 0xFF, 0x83, 0xFE, 0x0F, 0xF8, 0x3F, 0xE0, + 0xFF, 0x83, 0xFE, 0x0F, 0xF8, 0x3F, 0xE0, 0xFF, 0x83, 0xFE, 0x0F, 0xF8, + 0x3F, 0xE0, 0xFF, 0x83, 0xFE, 0x0F, 0xF8, 0x3F, 0xE0, 0xFF, 0x83, 0xFE, + 0x0F, 0xF8, 0x3F, 0xE0, 0xFF, 0x83, 0xFE, 0x0F, 0xF8, 0x1F, 0xF0, 0x7F, + 0xC1, 0xFF, 0x87, 0xFF, 0xCF, 0xFF, 0x3F, 0xFC, 0x7F, 0xF0, 0xFF, 0xC0, + 0xFF, 0x00, 0x0C, 0xF8, 0x03, 0xFE, 0x0F, 0xFC, 0x3F, 0xF8, 0xFF, 0xF3, + 0xFF, 0xEF, 0xFF, 0x83, 0xFE, 0x07, 0xFC, 0x1F, 0xF0, 0x7F, 0xC1, 0xFF, + 0x07, 0xFC, 0x1F, 0xF0, 0x7F, 0xC0, 0xFF, 0x03, 0xFC, 0x0F, 0xF0, 0x3F, + 0xC0, 0xFF, 0x03, 0xFC, 0x0F, 0xF0, 0x3F, 0xC0, 0xFF, 0x03, 0xFC, 0x0F, + 0xF0, 0x3F, 0xC0, 0xFF, 0x03, 0xFC, 0x0F, 0xF0, 0x3F, 0xC0, 0xFF, 0x03, + 0xFC, 0x0F, 0xF0, 0x3F, 0xC0, 0xFF, 0x03, 0xFC, 0x0F, 0xF0, 0x3F, 0xC0, + 0xFF, 0x03, 0xFC, 0x0F, 0xF0, 0x3F, 0xC0, 0xFF, 0x03, 0xFC, 0x0F, 0xF0, + 0x3F, 0xC0, 0xFF, 0x03, 0xFC, 0x0F, 0xF0, 0x3F, 0xC0, 0xFF, 0x03, 0xFC, + 0x0F, 0xF0, 0x3F, 0xC0, 0xFF, 0x03, 0xFC, 0x0F, 0xF0, 0x3F, 0xC0, 0xFF, + 0x03, 0xFC, 0x0F, 0xF0, 0x7F, 0xC1, 0xFF, 0x07, 0xFC, 0x1F, 0xF0, 0x7F, + 0xC1, 0xFF, 0x0F, 0xFC, 0x7F, 0xEF, 0xFF, 0xBF, 0xFE, 0xFF, 0xF3, 0xFF, + 0x8F, 0xFC, 0x3F, 0xC0, 0xC0, 0x00, 0x00, 0x1F, 0xC0, 0x00, 0x00, 0xFE, + 0x00, 0x00, 0x07, 0xE0, 0x00, 0x00, 0x3F, 0x00, 0x01, 0x00, 0xF8, 0x04, + 0x0C, 0x07, 0xC0, 0xE0, 0xF8, 0x3E, 0x0F, 0x8F, 0xE1, 0xF0, 0xFC, 0x7F, + 0x8F, 0x9F, 0xF7, 0xFF, 0x7D, 0xFF, 0xDF, 0xFF, 0xFF, 0xF8, 0x1F, 0xFF, + 0xFF, 0x00, 0x3F, 0xFF, 0xE0, 0x00, 0x7F, 0xFC, 0x00, 0x00, 0xFF, 0x80, + 0x00, 0x1F, 0xFF, 0x00, 0x03, 0xFF, 0xFE, 0x00, 0x7F, 0xFF, 0xFC, 0x0F, + 0xFF, 0xFF, 0xF9, 0xFF, 0xDF, 0x7F, 0xF7, 0xF8, 0xF9, 0xFF, 0x1F, 0x87, + 0xC3, 0xF8, 0xF8, 0x3E, 0x0F, 0x83, 0x01, 0xF0, 0x38, 0x10, 0x0F, 0x80, + 0x40, 0x00, 0xFC, 0x00, 0x00, 0x07, 0xE0, 0x00, 0x00, 0x3F, 0x80, 0x00, + 0x01, 0xFC, 0x00, 0x00, 0x00, 0x7E, 0x00, 0x00, 0x7E, 0x00, 0x00, 0x7E, + 0x00, 0x00, 0x7E, 0x00, 0x00, 0x7E, 0x00, 0x00, 0x7E, 0x00, 0x00, 0x7E, + 0x00, 0x00, 0x7E, 0x00, 0x00, 0x7E, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0x00, 0x7E, 0x00, 0x00, 0x7E, 0x00, 0x00, 0x7E, 0x00, 0x00, 0x7E, + 0x00, 0x00, 0x7E, 0x00, 0x00, 0x7E, 0x00, 0x00, 0x7E, 0x00, 0x00, 0x7E, + 0x00, 0x00, 0x7E, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0xFC, 0x3E, 0x0F, 0x83, 0xE1, 0xF0, 0x7C, + 0x1F, 0x07, 0xC3, 0xE0, 0xF8, 0x3E, 0x0F, 0x03, 0xC0, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, + 0xFF, 0x00, 0x00, 0xFE, 0x00, 0x01, 0xFE, 0x00, 0x01, 0xFE, 0x00, 0x01, + 0xFE, 0x00, 0x01, 0xFE, 0x00, 0x03, 0xFC, 0x00, 0x03, 0xFC, 0x00, 0x03, + 0xFC, 0x00, 0x03, 0xFC, 0x00, 0x07, 0xF8, 0x00, 0x07, 0xF8, 0x00, 0x07, + 0xF8, 0x00, 0x07, 0xF8, 0x00, 0x0F, 0xF0, 0x00, 0x0F, 0xF0, 0x00, 0x0F, + 0xF0, 0x00, 0x0F, 0xF0, 0x00, 0x1F, 0xE0, 0x00, 0x1F, 0xE0, 0x00, 0x1F, + 0xE0, 0x00, 0x1F, 0xE0, 0x00, 0x3F, 0xC0, 0x00, 0x3F, 0xC0, 0x00, 0x3F, + 0xC0, 0x00, 0x3F, 0xC0, 0x00, 0x7F, 0x80, 0x00, 0x7F, 0x80, 0x00, 0x7F, + 0x80, 0x00, 0x7F, 0x80, 0x00, 0x7F, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, + 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFE, 0x00, 0x01, 0xFE, 0x00, 0x01, 0xFE, + 0x00, 0x01, 0xFE, 0x00, 0x01, 0xFC, 0x00, 0x03, 0xFC, 0x00, 0x03, 0xFC, + 0x00, 0x03, 0xFC, 0x00, 0x03, 0xF8, 0x00, 0x07, 0xF8, 0x00, 0x07, 0xF8, + 0x00, 0x07, 0xF8, 0x00, 0x07, 0xF0, 0x00, 0x0F, 0xF0, 0x00, 0x0F, 0xF0, + 0x00, 0x0F, 0xF0, 0x00, 0x0F, 0xE0, 0x00, 0x1F, 0xE0, 0x00, 0x1F, 0xE0, + 0x00, 0x1F, 0xE0, 0x00, 0x1F, 0xC0, 0x00, 0x3F, 0xC0, 0x00, 0x3F, 0xC0, + 0x00, 0x3F, 0xC0, 0x00, 0x3F, 0x80, 0x00, 0x7F, 0x80, 0x00, 0x7F, 0x80, + 0x00, 0x7F, 0x80, 0x00, 0x7F, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, + 0x00, 0xFF, 0x00, 0x00, 0xFE, 0x00, 0x00, 0x00, 0x7F, 0xE0, 0x00, 0x7F, + 0xFF, 0x00, 0x1F, 0xFF, 0xF0, 0x07, 0xFF, 0xFF, 0x01, 0xFF, 0xFF, 0xF0, + 0x7F, 0xFF, 0xFF, 0x0F, 0xFF, 0xFF, 0xE1, 0xFF, 0xFF, 0xFC, 0x7F, 0xE0, + 0xFF, 0xCF, 0xF8, 0x0F, 0xF9, 0xFF, 0x01, 0xFF, 0x3F, 0xC0, 0x1F, 0xE7, + 0xF8, 0x03, 0xFC, 0xFF, 0x00, 0x7F, 0xBF, 0xE0, 0x0F, 0xF7, 0xFC, 0x01, + 0xFF, 0xFF, 0x80, 0x3F, 0xFF, 0xF0, 0x07, 0xFF, 0xFE, 0x00, 0xFF, 0xFF, + 0xC0, 0x1F, 0xFF, 0xF8, 0x03, 0xFF, 0xFF, 0x00, 0x7F, 0xFF, 0xE0, 0x0F, + 0xFF, 0xFC, 0x01, 0xFF, 0xFF, 0x80, 0x3F, 0xFF, 0xF0, 0x07, 0xFF, 0xFE, + 0x00, 0xFF, 0xFF, 0xC0, 0x1F, 0xFF, 0xF8, 0x03, 0xFF, 0xFF, 0x00, 0x7F, + 0xFF, 0xE0, 0x0F, 0xFF, 0xFC, 0x01, 0xFF, 0xFF, 0x80, 0x3F, 0xFF, 0xF0, + 0x07, 0xFF, 0xFE, 0x00, 0xFF, 0xFF, 0xC0, 0x1F, 0xFF, 0xF8, 0x03, 0xFF, + 0xFF, 0x00, 0x7F, 0xFF, 0xE0, 0x0F, 0xFF, 0xFC, 0x01, 0xFF, 0xFF, 0x80, + 0x3F, 0xFF, 0xF0, 0x07, 0xFF, 0xFE, 0x00, 0xFF, 0xFF, 0xC0, 0x1F, 0xFF, + 0xF8, 0x03, 0xFF, 0xFF, 0x00, 0x7F, 0xFF, 0xE0, 0x0F, 0xFF, 0xFC, 0x01, + 0xFF, 0xFF, 0x80, 0x3F, 0xFF, 0xF0, 0x07, 0xFF, 0xFE, 0x00, 0xFF, 0xFF, + 0xC0, 0x1F, 0xFF, 0xF8, 0x03, 0xFF, 0xFF, 0x00, 0x7F, 0xDF, 0xE0, 0x0F, + 0xF3, 0xFC, 0x01, 0xFE, 0x7F, 0x80, 0x3F, 0xCF, 0xF0, 0x0F, 0xF9, 0xFF, + 0x01, 0xFF, 0x3F, 0xE0, 0x3F, 0xE3, 0xFE, 0x0F, 0xFC, 0x7F, 0xFF, 0xFF, + 0x0F, 0xFF, 0xFF, 0xE0, 0xFF, 0xFF, 0xF8, 0x1F, 0xFF, 0xFF, 0x01, 0xFF, + 0xFF, 0xC0, 0x1F, 0xFF, 0xF0, 0x00, 0xFF, 0xF8, 0x00, 0x03, 0xF8, 0x00, + 0x00, 0x0F, 0xE0, 0x03, 0xFC, 0x00, 0x7F, 0x80, 0x1F, 0xF0, 0x0F, 0xFE, + 0x03, 0xFF, 0xC1, 0xFF, 0xF8, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF3, 0xFF, 0xF8, 0x7F, 0xF8, 0x0F, 0xF8, + 0x01, 0xFF, 0x00, 0x3F, 0xE0, 0x07, 0xFC, 0x00, 0xFF, 0x80, 0x1F, 0xF0, + 0x03, 0xFE, 0x00, 0x7F, 0xC0, 0x0F, 0xF8, 0x01, 0xFF, 0x00, 0x3F, 0xE0, + 0x07, 0xFC, 0x00, 0xFF, 0x80, 0x1F, 0xF0, 0x03, 0xFE, 0x00, 0x7F, 0xC0, + 0x0F, 0xF8, 0x01, 0xFF, 0x00, 0x3F, 0xE0, 0x07, 0xFC, 0x00, 0xFF, 0x80, + 0x1F, 0xF0, 0x03, 0xFE, 0x00, 0x7F, 0xC0, 0x0F, 0xF8, 0x01, 0xFF, 0x00, + 0x3F, 0xE0, 0x07, 0xFC, 0x00, 0xFF, 0x80, 0x1F, 0xF0, 0x03, 0xFE, 0x00, + 0x7F, 0xC0, 0x0F, 0xF8, 0x01, 0xFF, 0x00, 0x3F, 0xE0, 0x07, 0xFC, 0x00, + 0xFF, 0x80, 0x1F, 0xF0, 0x03, 0xFE, 0x00, 0x7F, 0xC0, 0x0F, 0xF8, 0x01, + 0xFF, 0x00, 0x3F, 0xE0, 0x07, 0xFC, 0x00, 0xFF, 0x80, 0x1F, 0xF0, 0x03, + 0xFE, 0x00, 0x7F, 0xC0, 0x0F, 0xF8, 0x01, 0xFF, 0x00, 0x3F, 0xE0, 0x07, + 0xFC, 0x00, 0xFF, 0x80, 0x00, 0x7F, 0x80, 0x01, 0xFF, 0xF0, 0x01, 0xFF, + 0xFE, 0x01, 0xFF, 0xFF, 0x01, 0xFF, 0xFF, 0xC1, 0xFF, 0xFF, 0xF0, 0xFF, + 0xFF, 0xF8, 0xFF, 0xFF, 0xFE, 0x7F, 0xC1, 0xFF, 0x3F, 0xE0, 0x7F, 0x9F, + 0xE0, 0x3F, 0xCF, 0xF0, 0x1F, 0xFF, 0xF8, 0x0F, 0xFF, 0xFC, 0x03, 0xFF, + 0xFE, 0x01, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0x7F, 0xFF, 0x80, 0x3F, + 0xFF, 0xC0, 0x1F, 0xFF, 0xE0, 0x0F, 0xFF, 0xF0, 0x07, 0xFF, 0xF8, 0x03, + 0xFF, 0xFC, 0x03, 0xFF, 0xFE, 0x01, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x80, + 0x7F, 0xBF, 0xC0, 0x3F, 0xC0, 0x00, 0x3F, 0xE0, 0x00, 0x1F, 0xF0, 0x00, + 0x0F, 0xF0, 0x00, 0x0F, 0xF8, 0x00, 0x07, 0xFC, 0x00, 0x07, 0xFC, 0x00, + 0x03, 0xFE, 0x00, 0x03, 0xFE, 0x00, 0x03, 0xFF, 0x00, 0x01, 0xFF, 0x00, + 0x01, 0xFF, 0x80, 0x00, 0xFF, 0x80, 0x00, 0xFF, 0x80, 0x00, 0xFF, 0xC0, + 0x00, 0x7F, 0xC0, 0x00, 0x7F, 0xE0, 0x00, 0x3F, 0xE0, 0x00, 0x3F, 0xF0, + 0x00, 0x1F, 0xF0, 0x00, 0x1F, 0xF8, 0x00, 0x0F, 0xF8, 0x00, 0x0F, 0xF8, + 0x00, 0x07, 0xFC, 0x00, 0x07, 0xFC, 0x00, 0x03, 0xFE, 0x00, 0x03, 0xFE, + 0x00, 0x01, 0xFF, 0x00, 0x00, 0xFF, 0x80, 0x00, 0xFF, 0x80, 0x00, 0x7F, + 0xC0, 0x00, 0x3F, 0xE0, 0x00, 0x1F, 0xE0, 0x00, 0x0F, 0xF0, 0x00, 0x07, + 0xF8, 0x00, 0x07, 0xFF, 0xFF, 0xFB, 0xFF, 0xFF, 0xFD, 0xFF, 0xFF, 0xFE, + 0xFF, 0xFF, 0xFF, 0x7F, 0xFF, 0xFF, 0xBF, 0xFF, 0xFF, 0xDF, 0xFF, 0xFF, + 0xE0, 0x00, 0x7F, 0xC0, 0x00, 0x7F, 0xFE, 0x00, 0x1F, 0xFF, 0xF0, 0x07, + 0xFF, 0xFF, 0x01, 0xFF, 0xFF, 0xF0, 0x7F, 0xFF, 0xFE, 0x0F, 0xFF, 0xFF, + 0xE3, 0xFF, 0xFF, 0xFC, 0x7F, 0xE0, 0xFF, 0xCF, 0xF8, 0x0F, 0xF9, 0xFF, + 0x01, 0xFF, 0x3F, 0xC0, 0x1F, 0xEF, 0xF8, 0x03, 0xFF, 0xFF, 0x00, 0x7F, + 0xFF, 0xE0, 0x0F, 0xFF, 0xFC, 0x01, 0xFF, 0xFF, 0x80, 0x3F, 0xFF, 0xF0, + 0x07, 0xFF, 0xFE, 0x00, 0xFF, 0x80, 0x00, 0x1F, 0xF0, 0x00, 0x03, 0xFE, + 0x00, 0x00, 0x7F, 0xC0, 0x00, 0x0F, 0xF8, 0x00, 0x01, 0xFE, 0x00, 0x00, + 0x3F, 0xC0, 0x00, 0x0F, 0xF8, 0x00, 0x01, 0xFF, 0x00, 0x00, 0x7F, 0xC0, + 0x00, 0x1F, 0xF8, 0x00, 0xFF, 0xFE, 0x00, 0x1F, 0xFF, 0x80, 0x03, 0xFF, + 0xE0, 0x00, 0x7F, 0xF0, 0x00, 0x0F, 0xFF, 0x80, 0x01, 0xFF, 0xF8, 0x00, + 0x3F, 0xFF, 0x80, 0x00, 0x3F, 0xF0, 0x00, 0x01, 0xFF, 0x00, 0x00, 0x1F, + 0xE0, 0x00, 0x03, 0xFE, 0x00, 0x00, 0x7F, 0xC0, 0x00, 0x07, 0xF8, 0x00, + 0x00, 0xFF, 0x00, 0x00, 0x1F, 0xF0, 0x00, 0x03, 0xFE, 0x00, 0x00, 0x7F, + 0xFF, 0xC0, 0x0F, 0xFF, 0xF8, 0x01, 0xFF, 0xFF, 0x00, 0x3F, 0xFF, 0xE0, + 0x07, 0xFF, 0xFC, 0x00, 0xFF, 0xFF, 0x80, 0x1F, 0xFF, 0xF0, 0x03, 0xFF, + 0xFF, 0x00, 0x7F, 0xFF, 0xE0, 0x0F, 0xFF, 0xFC, 0x01, 0xFF, 0xFF, 0x80, + 0x3F, 0xCF, 0xF0, 0x07, 0xF9, 0xFE, 0x01, 0xFF, 0x3F, 0xE0, 0x3F, 0xE7, + 0xFE, 0x0F, 0xF8, 0x7F, 0xFF, 0xFF, 0x0F, 0xFF, 0xFF, 0xE1, 0xFF, 0xFF, + 0xF8, 0x1F, 0xFF, 0xFE, 0x01, 0xFF, 0xFF, 0xC0, 0x1F, 0xFF, 0xE0, 0x00, + 0xFF, 0xF8, 0x00, 0x03, 0xF0, 0x00, 0x00, 0x01, 0xFF, 0x00, 0x00, 0x07, + 0xFC, 0x00, 0x00, 0x3F, 0xF0, 0x00, 0x00, 0xFF, 0xC0, 0x00, 0x03, 0xFF, + 0x00, 0x00, 0x1F, 0xFC, 0x00, 0x00, 0x7F, 0xF0, 0x00, 0x01, 0xFF, 0xC0, + 0x00, 0x0F, 0xFF, 0x00, 0x00, 0x3F, 0xFC, 0x00, 0x00, 0xFF, 0xF0, 0x00, + 0x07, 0xFF, 0xC0, 0x00, 0x1F, 0xFF, 0x00, 0x00, 0x7F, 0xFC, 0x00, 0x01, + 0xFF, 0xF0, 0x00, 0x0F, 0xFF, 0xC0, 0x00, 0x3F, 0xFF, 0x00, 0x00, 0xFB, + 0xFC, 0x00, 0x07, 0xEF, 0xF0, 0x00, 0x1F, 0xBF, 0xC0, 0x00, 0x7E, 0xFF, + 0x00, 0x03, 0xF3, 0xFC, 0x00, 0x0F, 0xCF, 0xF0, 0x00, 0x3F, 0x3F, 0xC0, + 0x00, 0xF8, 0xFF, 0x00, 0x07, 0xE3, 0xFC, 0x00, 0x1F, 0x8F, 0xF0, 0x00, + 0x7E, 0x3F, 0xC0, 0x03, 0xF0, 0xFF, 0x00, 0x0F, 0xC3, 0xFC, 0x00, 0x3F, + 0x0F, 0xF0, 0x01, 0xFC, 0x3F, 0xC0, 0x07, 0xE0, 0xFF, 0x00, 0x1F, 0x83, + 0xFC, 0x00, 0xFE, 0x0F, 0xF0, 0x03, 0xF8, 0x3F, 0xC0, 0x0F, 0xC0, 0xFF, + 0x00, 0x3F, 0x03, 0xFC, 0x01, 0xFC, 0x0F, 0xF0, 0x07, 0xE0, 0x3F, 0xC0, + 0x1F, 0x80, 0xFF, 0x00, 0xFE, 0x03, 0xFC, 0x03, 0xF8, 0x0F, 0xF0, 0x0F, + 0xC0, 0x3F, 0xC0, 0x7F, 0x00, 0xFF, 0x01, 0xFC, 0x03, 0xFC, 0x07, 0xF0, + 0x0F, 0xF0, 0x3F, 0x80, 0x3F, 0xC0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0x3F, 0xC0, + 0x00, 0x00, 0xFF, 0x00, 0x00, 0x03, 0xFC, 0x00, 0x00, 0x0F, 0xF0, 0x00, + 0x00, 0x3F, 0xC0, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x03, 0xFC, 0x00, 0x00, + 0x0F, 0xF0, 0x00, 0x00, 0x3F, 0xC0, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x03, + 0xFC, 0x00, 0x00, 0x0F, 0xF0, 0x00, 0x7F, 0xFF, 0xFE, 0x3F, 0xFF, 0xFF, + 0x1F, 0xFF, 0xFF, 0x8F, 0xFF, 0xFF, 0xC7, 0xFF, 0xFF, 0xE3, 0xFF, 0xFF, + 0xF1, 0xFF, 0xFF, 0xF8, 0xFF, 0xFF, 0xFC, 0x7F, 0x80, 0x00, 0x3F, 0xC0, + 0x00, 0x1F, 0xE0, 0x00, 0x0F, 0xF0, 0x00, 0x07, 0xF8, 0x00, 0x03, 0xFC, + 0x00, 0x01, 0xFE, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x7F, 0x80, 0x00, 0x3F, + 0xC0, 0x00, 0x1F, 0xE0, 0x00, 0x0F, 0xF0, 0x00, 0x07, 0xF9, 0xFE, 0x03, + 0xFD, 0xFF, 0xC1, 0xFF, 0xFF, 0xF0, 0xFF, 0xFF, 0xF8, 0x7F, 0xFF, 0xFE, + 0x3F, 0xFF, 0xFF, 0x1F, 0xFF, 0xFF, 0xCF, 0xFC, 0x7F, 0xE7, 0xFC, 0x1F, + 0xF3, 0xFC, 0x07, 0xF9, 0xFE, 0x03, 0xFC, 0xFF, 0x01, 0xFF, 0x7F, 0x80, + 0xFF, 0x8F, 0x80, 0x7F, 0xC0, 0x00, 0x1F, 0xE0, 0x00, 0x0F, 0xF0, 0x00, + 0x07, 0xF8, 0x00, 0x03, 0xFC, 0x00, 0x01, 0xFE, 0x00, 0x00, 0xFF, 0x00, + 0x00, 0x7F, 0x80, 0x00, 0x3F, 0xC0, 0x00, 0x1F, 0xE0, 0x00, 0x0F, 0xF0, + 0x00, 0x07, 0xF8, 0x00, 0x03, 0xFC, 0x00, 0x01, 0xFF, 0xFF, 0x00, 0xFF, + 0xFF, 0x80, 0x7F, 0xFF, 0xC0, 0x3F, 0xFF, 0xE0, 0x1F, 0xFF, 0xF0, 0x0F, + 0xFF, 0xF8, 0x07, 0xFF, 0xFC, 0x03, 0xFF, 0xFE, 0x03, 0xFF, 0xFF, 0x01, + 0xFF, 0xFF, 0x80, 0xFF, 0x7F, 0xC0, 0x7F, 0xBF, 0xE0, 0x3F, 0xCF, 0xF8, + 0x3F, 0xE7, 0xFF, 0xFF, 0xF3, 0xFF, 0xFF, 0xF0, 0xFF, 0xFF, 0xF8, 0x7F, + 0xFF, 0xF8, 0x1F, 0xFF, 0xFC, 0x07, 0xFF, 0xF8, 0x00, 0xFF, 0xF8, 0x00, + 0x07, 0xC0, 0x00, 0x00, 0x7F, 0xE0, 0x00, 0x3F, 0xFF, 0x00, 0x1F, 0xFF, + 0xF0, 0x07, 0xFF, 0xFF, 0x01, 0xFF, 0xFF, 0xF0, 0x3F, 0xFF, 0xFE, 0x0F, + 0xFF, 0xFF, 0xE1, 0xFF, 0xFF, 0xFC, 0x3F, 0xE0, 0x7F, 0x8F, 0xF8, 0x0F, + 0xF9, 0xFF, 0x00, 0xFF, 0x3F, 0xC0, 0x1F, 0xE7, 0xF8, 0x03, 0xFC, 0xFF, + 0x00, 0x7F, 0x9F, 0xE0, 0x0F, 0xF3, 0xFC, 0x01, 0xFE, 0xFF, 0x80, 0x3F, + 0xDF, 0xF0, 0x07, 0xFB, 0xFE, 0x00, 0xFF, 0x7F, 0xC0, 0x1F, 0xEF, 0xF8, + 0x00, 0x01, 0xFF, 0x00, 0x00, 0x3F, 0xE0, 0x00, 0x07, 0xFC, 0x00, 0x00, + 0xFF, 0x80, 0x00, 0x1F, 0xF0, 0x00, 0x03, 0xFE, 0x3F, 0xC0, 0x7F, 0xDF, + 0xFE, 0x0F, 0xFF, 0xFF, 0xE1, 0xFF, 0xFF, 0xFE, 0x3F, 0xFF, 0xFF, 0xE7, + 0xFF, 0xFF, 0xFC, 0xFF, 0xFF, 0xFF, 0xDF, 0xFF, 0x3F, 0xFB, 0xFF, 0x01, + 0xFF, 0x7F, 0xC0, 0x1F, 0xEF, 0xF8, 0x03, 0xFF, 0xFF, 0x00, 0x3F, 0xFF, + 0xE0, 0x07, 0xFF, 0xFC, 0x00, 0xFF, 0xFF, 0x80, 0x1F, 0xFF, 0xF0, 0x03, + 0xFF, 0xFE, 0x00, 0x7F, 0xFF, 0xC0, 0x0F, 0xFF, 0xF8, 0x01, 0xFF, 0xFF, + 0x00, 0x3F, 0xFF, 0xE0, 0x07, 0xFF, 0xFC, 0x00, 0xFF, 0xFF, 0x80, 0x1F, + 0xFF, 0xF0, 0x03, 0xFF, 0xFE, 0x00, 0x7F, 0xFF, 0xC0, 0x0F, 0xFF, 0xF8, + 0x01, 0xFE, 0xFF, 0x00, 0x3F, 0xDF, 0xE0, 0x07, 0xFB, 0xFC, 0x00, 0xFF, + 0x7F, 0x80, 0x1F, 0xEF, 0xF8, 0x03, 0xFD, 0xFF, 0x00, 0xFF, 0xBF, 0xF0, + 0x1F, 0xE3, 0xFF, 0x07, 0xFC, 0x7F, 0xFF, 0xFF, 0x8F, 0xFF, 0xFF, 0xE0, + 0xFF, 0xFF, 0xFC, 0x0F, 0xFF, 0xFF, 0x01, 0xFF, 0xFF, 0xE0, 0x0F, 0xFF, + 0xF0, 0x00, 0xFF, 0xFC, 0x00, 0x03, 0xFC, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x01, 0xFE, + 0x00, 0x00, 0x3F, 0xE0, 0x00, 0x03, 0xFE, 0x00, 0x00, 0x7F, 0xC0, 0x00, + 0x07, 0xFC, 0x00, 0x00, 0x7F, 0xC0, 0x00, 0x0F, 0xF8, 0x00, 0x00, 0xFF, + 0x80, 0x00, 0x0F, 0xF0, 0x00, 0x01, 0xFF, 0x00, 0x00, 0x1F, 0xF0, 0x00, + 0x01, 0xFE, 0x00, 0x00, 0x3F, 0xE0, 0x00, 0x03, 0xFE, 0x00, 0x00, 0x3F, + 0xC0, 0x00, 0x07, 0xFC, 0x00, 0x00, 0x7F, 0xC0, 0x00, 0x07, 0xFC, 0x00, + 0x00, 0x7F, 0x80, 0x00, 0x0F, 0xF8, 0x00, 0x00, 0xFF, 0x80, 0x00, 0x0F, + 0xF0, 0x00, 0x01, 0xFF, 0x00, 0x00, 0x1F, 0xF0, 0x00, 0x01, 0xFE, 0x00, + 0x00, 0x3F, 0xE0, 0x00, 0x03, 0xFE, 0x00, 0x00, 0x3F, 0xE0, 0x00, 0x03, + 0xFC, 0x00, 0x00, 0x7F, 0xC0, 0x00, 0x07, 0xFC, 0x00, 0x00, 0x7F, 0xC0, + 0x00, 0x0F, 0xFC, 0x00, 0x00, 0xFF, 0x80, 0x00, 0x0F, 0xF8, 0x00, 0x00, + 0xFF, 0x80, 0x00, 0x1F, 0xF8, 0x00, 0x01, 0xFF, 0x00, 0x00, 0x1F, 0xF0, + 0x00, 0x01, 0xFF, 0x00, 0x00, 0x1F, 0xF0, 0x00, 0x03, 0xFF, 0x00, 0x00, + 0x3F, 0xF0, 0x00, 0x03, 0xFE, 0x00, 0x00, 0x3F, 0xE0, 0x00, 0x03, 0xFE, + 0x00, 0x00, 0x7F, 0xE0, 0x00, 0x07, 0xFE, 0x00, 0x00, 0x7F, 0xE0, 0x00, + 0x07, 0xFE, 0x00, 0x00, 0x7F, 0xC0, 0x00, 0x07, 0xFC, 0x00, 0x00, 0x7F, + 0xC0, 0x00, 0x07, 0xFC, 0x00, 0x00, 0xFF, 0xC0, 0x00, 0x0F, 0xFC, 0x00, + 0x00, 0xFF, 0xC0, 0x00, 0x0F, 0xFC, 0x00, 0x00, 0xFF, 0xC0, 0x00, 0x0F, + 0xFC, 0x00, 0x00, 0x00, 0xFF, 0xC0, 0x00, 0x7F, 0xFF, 0x00, 0x3F, 0xFF, + 0xF0, 0x0F, 0xFF, 0xFF, 0x01, 0xFF, 0xFF, 0xF0, 0x7F, 0xFF, 0xFF, 0x1F, + 0xFF, 0xFF, 0xE3, 0xFF, 0x07, 0xFC, 0x7F, 0xC0, 0x7F, 0xCF, 0xF0, 0x0F, + 0xFB, 0xFE, 0x01, 0xFF, 0x7F, 0xC0, 0x1F, 0xEF, 0xF8, 0x03, 0xFD, 0xFF, + 0x00, 0x7F, 0xBF, 0xE0, 0x0F, 0xFF, 0xFC, 0x01, 0xFF, 0xFF, 0x80, 0x3F, + 0xFF, 0xF0, 0x07, 0xFF, 0xFE, 0x00, 0xFF, 0xFF, 0xC0, 0x1F, 0xEF, 0xF8, + 0x03, 0xFD, 0xFF, 0x00, 0x7F, 0xBF, 0xE0, 0x0F, 0xF3, 0xFC, 0x01, 0xFE, + 0x7F, 0x80, 0x7F, 0xCF, 0xF0, 0x0F, 0xF1, 0xFF, 0x01, 0xFE, 0x1F, 0xE0, + 0x7F, 0xC3, 0xFE, 0x1F, 0xF0, 0x3F, 0xFF, 0xFE, 0x03, 0xFF, 0xFF, 0x80, + 0x3F, 0xFF, 0xC0, 0x0F, 0xFF, 0xFC, 0x03, 0xFF, 0xFF, 0xC0, 0x7F, 0xFF, + 0xFC, 0x1F, 0xF8, 0xFF, 0x83, 0xFE, 0x0F, 0xF8, 0xFF, 0x81, 0xFF, 0x1F, + 0xF0, 0x1F, 0xE3, 0xFC, 0x03, 0xFE, 0xFF, 0x80, 0x7F, 0xDF, 0xF0, 0x0F, + 0xFB, 0xFE, 0x00, 0xFF, 0x7F, 0xC0, 0x1F, 0xEF, 0xF8, 0x03, 0xFF, 0xFE, + 0x00, 0x7F, 0xFF, 0xC0, 0x0F, 0xFF, 0xF8, 0x01, 0xFF, 0xFF, 0x00, 0x3F, + 0xFF, 0xE0, 0x07, 0xFF, 0xFC, 0x00, 0xFF, 0xFF, 0x80, 0x1F, 0xFF, 0xF0, + 0x03, 0xFF, 0xFE, 0x00, 0x7F, 0xFF, 0xE0, 0x0F, 0xFF, 0xFC, 0x01, 0xFE, + 0xFF, 0x80, 0x3F, 0xDF, 0xF0, 0x0F, 0xFB, 0xFE, 0x01, 0xFF, 0x7F, 0xE0, + 0x3F, 0xE7, 0xFC, 0x0F, 0xFC, 0xFF, 0xFF, 0xFF, 0x0F, 0xFF, 0xFF, 0xE1, + 0xFF, 0xFF, 0xF8, 0x1F, 0xFF, 0xFF, 0x01, 0xFF, 0xFF, 0xC0, 0x1F, 0xFF, + 0xF0, 0x00, 0xFF, 0xF8, 0x00, 0x03, 0xF8, 0x00, 0x00, 0x7F, 0xC0, 0x00, + 0x7F, 0xFF, 0x00, 0x1F, 0xFF, 0xF0, 0x07, 0xFF, 0xFF, 0x01, 0xFF, 0xFF, + 0xF0, 0x3F, 0xFF, 0xFF, 0x0F, 0xFF, 0xFF, 0xE1, 0xFF, 0xFF, 0xFE, 0x7F, + 0xE0, 0xFF, 0xCF, 0xF8, 0x0F, 0xF9, 0xFE, 0x01, 0xFF, 0x3F, 0xC0, 0x1F, + 0xE7, 0xF8, 0x03, 0xFE, 0xFF, 0x00, 0x7F, 0xDF, 0xE0, 0x0F, 0xFF, 0xFC, + 0x01, 0xFF, 0xFF, 0x80, 0x3F, 0xFF, 0xF0, 0x07, 0xFF, 0xFE, 0x00, 0xFF, + 0xFF, 0xC0, 0x1F, 0xFF, 0xF8, 0x03, 0xFF, 0xFF, 0x00, 0x7F, 0xFF, 0xE0, + 0x0F, 0xFF, 0xFC, 0x01, 0xFF, 0xFF, 0x80, 0x3F, 0xFF, 0xF0, 0x07, 0xFF, + 0xFE, 0x00, 0xFF, 0xFF, 0xC0, 0x1F, 0xF7, 0xF8, 0x03, 0xFE, 0xFF, 0x00, + 0x7F, 0xDF, 0xE0, 0x0F, 0xFB, 0xFC, 0x01, 0xFF, 0x7F, 0x80, 0x3F, 0xEF, + 0xF8, 0x07, 0xFC, 0xFF, 0x81, 0xFF, 0x9F, 0xFF, 0xFF, 0xF3, 0xFF, 0xFF, + 0xFE, 0x3F, 0xFF, 0xFF, 0xC7, 0xFF, 0xFF, 0xF8, 0x7F, 0xFF, 0xFF, 0x07, + 0xFF, 0xFF, 0xE0, 0x7F, 0xF7, 0xFC, 0x00, 0xF0, 0xFF, 0x80, 0x00, 0x1F, + 0xF0, 0x00, 0x03, 0xFE, 0x00, 0x00, 0x7F, 0xC0, 0x00, 0x0F, 0xF8, 0x00, + 0x01, 0xFF, 0x7F, 0xC0, 0x3F, 0xEF, 0xF8, 0x07, 0xFD, 0xFF, 0x00, 0xFF, + 0xBF, 0xE0, 0x1F, 0xF7, 0xFC, 0x03, 0xFE, 0xFF, 0x80, 0x7F, 0xDF, 0xF0, + 0x0F, 0xFB, 0xFE, 0x01, 0xFE, 0x3F, 0xC0, 0x3F, 0xC7, 0xF8, 0x07, 0xF8, + 0xFF, 0x00, 0xFF, 0x1F, 0xF0, 0x3F, 0xE3, 0xFE, 0x07, 0xFC, 0x3F, 0xFF, + 0xFF, 0x07, 0xFF, 0xFF, 0xE0, 0xFF, 0xFF, 0xF8, 0x0F, 0xFF, 0xFF, 0x00, + 0xFF, 0xFF, 0xC0, 0x0F, 0xFF, 0xF0, 0x00, 0xFF, 0xF8, 0x00, 0x01, 0xF8, + 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x07, 0xFD, 0xFF, 0x7F, 0xDF, 0xF7, 0xFD, 0xFF, + 0x7F, 0xDF, 0xF7, 0xFD, 0xFF, 0x0F, 0xC3, 0xF0, 0xFC, 0x7E, 0x1F, 0x87, + 0xE1, 0xF0, 0x7C, 0x3F, 0x0F, 0xC3, 0xE0, 0xF8, 0x7E, 0x1F, 0x00, 0x00, + 0x00, 0x04, 0x00, 0x00, 0x30, 0x00, 0x01, 0xC0, 0x00, 0x1F, 0x00, 0x00, + 0xFC, 0x00, 0x0F, 0xF0, 0x00, 0x7F, 0xC0, 0x07, 0xFF, 0x00, 0x3F, 0xFC, + 0x03, 0xFF, 0xF0, 0x1F, 0xFF, 0x81, 0xFF, 0xF8, 0x0F, 0xFF, 0x80, 0xFF, + 0xFC, 0x0F, 0xFF, 0xC0, 0x3F, 0xFE, 0x00, 0xFF, 0xE0, 0x03, 0xFE, 0x00, + 0x0F, 0xF0, 0x00, 0x3F, 0x80, 0x00, 0xFF, 0x80, 0x03, 0xFF, 0x00, 0x0F, + 0xFF, 0x00, 0x3F, 0xFE, 0x00, 0x7F, 0xFE, 0x00, 0x7F, 0xFE, 0x00, 0xFF, + 0xFC, 0x00, 0xFF, 0xFC, 0x01, 0xFF, 0xF8, 0x01, 0xFF, 0xF0, 0x01, 0xFF, + 0xC0, 0x03, 0xFF, 0x00, 0x03, 0xFC, 0x00, 0x07, 0xF0, 0x00, 0x07, 0xC0, + 0x00, 0x0F, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x10, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x80, 0x00, + 0x03, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x3E, 0x00, 0x00, 0xFE, 0x00, 0x03, + 0xFE, 0x00, 0x0F, 0xFC, 0x00, 0x3F, 0xFC, 0x00, 0xFF, 0xF8, 0x01, 0xFF, + 0xF8, 0x03, 0xFF, 0xF0, 0x03, 0xFF, 0xF0, 0x07, 0xFF, 0xE0, 0x07, 0xFF, + 0xE0, 0x07, 0xFF, 0xC0, 0x0F, 0xFF, 0x00, 0x0F, 0xFC, 0x00, 0x1F, 0xF0, + 0x00, 0x1F, 0xC0, 0x00, 0x3F, 0x00, 0x03, 0xFC, 0x00, 0x1F, 0xF0, 0x01, + 0xFF, 0xC0, 0x1F, 0xFF, 0x00, 0xFF, 0xFC, 0x0F, 0xFF, 0xC0, 0x7F, 0xFC, + 0x07, 0xFF, 0xE0, 0x7F, 0xFE, 0x03, 0xFF, 0xF0, 0x0F, 0xFF, 0x00, 0x3F, + 0xF8, 0x00, 0xFF, 0x80, 0x03, 0xFC, 0x00, 0x0F, 0xC0, 0x00, 0x3E, 0x00, + 0x00, 0xE0, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x80, 0x03, 0xFF, + 0xF0, 0x0F, 0xFF, 0xF8, 0x1F, 0xFF, 0xFC, 0x1F, 0xFF, 0xFC, 0x3F, 0xFF, + 0xFE, 0x3F, 0xFF, 0xFE, 0x7F, 0xFF, 0xFE, 0x7F, 0xC1, 0xFF, 0x7F, 0xC1, + 0xFF, 0x7F, 0x81, 0xFF, 0x7F, 0x81, 0xFF, 0x7F, 0x81, 0xFF, 0xFF, 0x81, + 0xFF, 0xFF, 0x81, 0xFF, 0xFF, 0x81, 0xFF, 0xFF, 0x81, 0xFF, 0xFF, 0x81, + 0xFF, 0xFF, 0x81, 0xFF, 0xFF, 0x81, 0xFF, 0xFF, 0x81, 0xFF, 0xFF, 0x81, + 0xFF, 0xFF, 0x81, 0xFF, 0xFF, 0x81, 0xFF, 0x00, 0x01, 0xFF, 0x00, 0x01, + 0xFF, 0x00, 0x01, 0xFF, 0x00, 0x01, 0xFF, 0x00, 0x01, 0xFF, 0x00, 0x03, + 0xFE, 0x00, 0x03, 0xFE, 0x00, 0x03, 0xFE, 0x00, 0x07, 0xFE, 0x00, 0x0F, + 0xFC, 0x00, 0x1F, 0xFC, 0x00, 0x7F, 0xF8, 0x03, 0xFF, 0xF0, 0x07, 0xFF, + 0xE0, 0x07, 0xFF, 0xC0, 0x07, 0xFF, 0x00, 0x07, 0xFC, 0x00, 0x07, 0xF8, + 0x00, 0x07, 0xF8, 0x00, 0x07, 0xF8, 0x00, 0x07, 0xF8, 0x00, 0x07, 0xF8, + 0x00, 0x07, 0xF8, 0x00, 0x07, 0xF8, 0x00, 0x07, 0xF8, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xF8, + 0x00, 0x07, 0xF8, 0x00, 0x07, 0xF8, 0x00, 0x07, 0xF8, 0x00, 0x07, 0xF8, + 0x00, 0x07, 0xF8, 0x00, 0x07, 0xF8, 0x00, 0x07, 0xF8, 0x00, 0x07, 0xF8, + 0x00, 0x07, 0xF8, 0x00, 0x07, 0xF8, 0x00, 0x00, 0x00, 0x07, 0xFE, 0x00, + 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xC0, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xF8, + 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xFC, 0x00, 0x00, 0x1F, 0xFF, 0xFF, 0xFE, + 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x7F, 0xF0, 0x01, 0xFF, + 0x80, 0x00, 0xFF, 0xC0, 0x00, 0x7F, 0xC0, 0x01, 0xFF, 0x00, 0x00, 0x1F, + 0xE0, 0x03, 0xFE, 0x00, 0x00, 0x0F, 0xE0, 0x07, 0xF8, 0x00, 0x00, 0x07, + 0xF0, 0x07, 0xF8, 0x00, 0x00, 0x03, 0xF0, 0x0F, 0xF0, 0x00, 0x00, 0x03, + 0xF8, 0x0F, 0xE0, 0x00, 0x00, 0x01, 0xF8, 0x1F, 0xC0, 0x00, 0x00, 0x00, + 0xFC, 0x1F, 0xC0, 0x00, 0x00, 0x00, 0xFC, 0x3F, 0xC0, 0x07, 0xFE, 0x00, + 0xFC, 0x3F, 0x80, 0x1F, 0xFF, 0xC0, 0x7E, 0x3F, 0x80, 0x3F, 0xFF, 0xF0, + 0x7E, 0x7F, 0x00, 0x7F, 0xFF, 0xF0, 0x7E, 0x7F, 0x00, 0xFF, 0xFF, 0xF0, + 0x7E, 0x7F, 0x00, 0xFE, 0x03, 0xF0, 0x3E, 0x7F, 0x01, 0xFC, 0x03, 0xF0, + 0x3F, 0x7E, 0x01, 0xF8, 0x03, 0xF0, 0x3F, 0xFE, 0x03, 0xF8, 0x03, 0xF0, + 0x3F, 0xFE, 0x03, 0xF0, 0x03, 0xF0, 0x3F, 0xFE, 0x03, 0xF0, 0x03, 0xF0, + 0x3F, 0xFE, 0x03, 0xE0, 0x03, 0xF0, 0x3F, 0xFE, 0x07, 0xE0, 0x03, 0xF0, + 0x3F, 0xFE, 0x07, 0xE0, 0x03, 0xF0, 0x3F, 0xFE, 0x07, 0xE0, 0x03, 0xF0, + 0x3F, 0xFC, 0x07, 0xE0, 0x03, 0xF0, 0x3F, 0xFC, 0x07, 0xE0, 0x03, 0xF0, + 0x3F, 0xFC, 0x07, 0xE0, 0x03, 0xF0, 0x3F, 0xFC, 0x07, 0xE0, 0x03, 0xF0, + 0x3F, 0xFC, 0x07, 0xE0, 0x03, 0xF0, 0x3F, 0xFC, 0x07, 0xE0, 0x03, 0xF0, + 0x3F, 0xFC, 0x07, 0xE0, 0x03, 0xF0, 0x3F, 0xFC, 0x07, 0xE0, 0x03, 0xF0, + 0x3F, 0xFC, 0x07, 0xE0, 0x03, 0xF0, 0x3F, 0xFC, 0x07, 0xE0, 0x03, 0xF0, + 0x3F, 0xFE, 0x07, 0xE0, 0x07, 0xF0, 0x3F, 0xFE, 0x07, 0xE0, 0x07, 0xF0, + 0x3F, 0xFE, 0x07, 0xE0, 0x07, 0xF0, 0x3E, 0xFE, 0x07, 0xE0, 0x07, 0xF0, + 0x7E, 0xFE, 0x07, 0xF0, 0x07, 0xF0, 0x7E, 0xFE, 0x03, 0xF0, 0x0F, 0xF0, + 0x7E, 0x7E, 0x03, 0xF0, 0x1D, 0xF0, 0xFC, 0x7F, 0x01, 0xF8, 0x1D, 0xFD, + 0xFC, 0x7F, 0x01, 0xFF, 0xFC, 0xFF, 0xF8, 0x7F, 0x00, 0xFF, 0xF8, 0xFF, + 0xF8, 0x3F, 0x80, 0xFF, 0xF8, 0x7F, 0xF0, 0x3F, 0x80, 0x7F, 0xF0, 0x3F, + 0xE0, 0x3F, 0x80, 0x3F, 0xE0, 0x1F, 0xC0, 0x1F, 0xC0, 0x0F, 0xC0, 0x00, + 0x00, 0x1F, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x1F, 0xE0, 0x00, 0x00, 0x00, + 0x00, 0x0F, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x07, 0xF0, 0x00, 0x00, 0x00, + 0x00, 0x07, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x03, 0xFE, 0x00, 0x00, 0x00, + 0x00, 0x01, 0xFF, 0x00, 0x00, 0x00, 0x80, 0x01, 0xFF, 0xC0, 0x00, 0x07, + 0x80, 0x00, 0xFF, 0xF8, 0x00, 0x7F, 0xC0, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, + 0xC0, 0x00, 0x1F, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, + 0xC0, 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0xFF, 0xFF, 0xFC, + 0x00, 0x00, 0x00, 0x1F, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x7F, 0xF8, 0x00, 0x00, 0xFF, 0xF0, 0x00, 0x01, 0xFF, 0xE0, + 0x00, 0x03, 0xFF, 0xC0, 0x00, 0x07, 0xFF, 0x80, 0x00, 0x0F, 0xFF, 0x80, + 0x00, 0x3F, 0xFF, 0x00, 0x00, 0x7F, 0xFE, 0x00, 0x00, 0xFF, 0xFC, 0x00, + 0x01, 0xFF, 0xF8, 0x00, 0x03, 0xFF, 0xF0, 0x00, 0x07, 0xFF, 0xF0, 0x00, + 0x0F, 0xFF, 0xE0, 0x00, 0x3F, 0xFF, 0xC0, 0x00, 0x7F, 0xBF, 0x80, 0x00, + 0xFF, 0x7F, 0x00, 0x01, 0xFE, 0xFE, 0x00, 0x03, 0xFD, 0xFE, 0x00, 0x07, + 0xF3, 0xFC, 0x00, 0x0F, 0xE7, 0xF8, 0x00, 0x3F, 0xCF, 0xF0, 0x00, 0x7F, + 0x8F, 0xE0, 0x00, 0xFF, 0x1F, 0xC0, 0x01, 0xFE, 0x3F, 0xC0, 0x03, 0xFC, + 0x7F, 0x80, 0x07, 0xF8, 0xFF, 0x00, 0x0F, 0xE1, 0xFE, 0x00, 0x3F, 0xC3, + 0xFC, 0x00, 0x7F, 0x83, 0xF8, 0x00, 0xFF, 0x07, 0xF0, 0x01, 0xFE, 0x0F, + 0xF0, 0x03, 0xFC, 0x1F, 0xE0, 0x07, 0xF8, 0x3F, 0xC0, 0x0F, 0xE0, 0x7F, + 0x80, 0x3F, 0xC0, 0xFF, 0x00, 0x7F, 0x80, 0xFE, 0x00, 0xFF, 0x01, 0xFE, + 0x01, 0xFE, 0x03, 0xFC, 0x03, 0xFC, 0x07, 0xF8, 0x07, 0xF8, 0x0F, 0xF0, + 0x1F, 0xF0, 0x1F, 0xE0, 0x3F, 0xC0, 0x3F, 0xC0, 0x7F, 0x80, 0x3F, 0xC0, + 0xFF, 0x00, 0x7F, 0x81, 0xFE, 0x00, 0xFF, 0x03, 0xFC, 0x01, 0xFE, 0x07, + 0xF8, 0x03, 0xFC, 0x1F, 0xFF, 0xFF, 0xF8, 0x3F, 0xFF, 0xFF, 0xF8, 0x7F, + 0xFF, 0xFF, 0xF0, 0xFF, 0xFF, 0xFF, 0xE1, 0xFF, 0xFF, 0xFF, 0xC3, 0xFF, + 0xFF, 0xFF, 0x87, 0xFF, 0xFF, 0xFF, 0x1F, 0xFF, 0xFF, 0xFE, 0x3F, 0xE0, + 0x03, 0xFE, 0x7F, 0x80, 0x03, 0xFC, 0xFF, 0x00, 0x07, 0xF9, 0xFE, 0x00, + 0x0F, 0xF3, 0xFC, 0x00, 0x1F, 0xE7, 0xF8, 0x00, 0x3F, 0xDF, 0xF0, 0x00, + 0x7F, 0xFF, 0xE0, 0x00, 0xFF, 0xFF, 0xC0, 0x00, 0xFF, 0xFF, 0x00, 0x01, + 0xFF, 0xFE, 0x00, 0x03, 0xFF, 0xFC, 0x00, 0x07, 0xF8, 0xFF, 0xFF, 0xF0, + 0x0F, 0xFF, 0xFF, 0xC0, 0xFF, 0xFF, 0xFE, 0x0F, 0xFF, 0xFF, 0xF0, 0xFF, + 0xFF, 0xFF, 0x8F, 0xFF, 0xFF, 0xF8, 0xFF, 0xFF, 0xFF, 0xCF, 0xF8, 0x0F, + 0xFC, 0xFF, 0x80, 0x7F, 0xCF, 0xF8, 0x03, 0xFE, 0xFF, 0x80, 0x3F, 0xEF, + 0xF8, 0x03, 0xFE, 0xFF, 0x80, 0x3F, 0xEF, 0xF8, 0x03, 0xFE, 0xFF, 0x80, + 0x3F, 0xEF, 0xF8, 0x03, 0xFE, 0xFF, 0x80, 0x3F, 0xEF, 0xF8, 0x03, 0xFE, + 0xFF, 0x80, 0x3F, 0xEF, 0xF8, 0x03, 0xFE, 0xFF, 0x80, 0x3F, 0xEF, 0xF8, + 0x03, 0xFE, 0xFF, 0x80, 0x3F, 0xCF, 0xF8, 0x03, 0xFC, 0xFF, 0x80, 0x3F, + 0xCF, 0xF8, 0x07, 0xFC, 0xFF, 0x80, 0x7F, 0x8F, 0xFF, 0xFF, 0xF8, 0xFF, + 0xFF, 0xFF, 0x0F, 0xFF, 0xFF, 0xE0, 0xFF, 0xFF, 0xFC, 0x0F, 0xFF, 0xFF, + 0xE0, 0xFF, 0xFF, 0xFF, 0x8F, 0xFF, 0xFF, 0xF8, 0xFF, 0x80, 0xFF, 0xCF, + 0xF8, 0x07, 0xFC, 0xFF, 0x80, 0x3F, 0xEF, 0xF8, 0x03, 0xFE, 0xFF, 0x80, + 0x1F, 0xEF, 0xF8, 0x01, 0xFF, 0xFF, 0x80, 0x1F, 0xFF, 0xF8, 0x01, 0xFF, + 0xFF, 0x80, 0x1F, 0xFF, 0xF8, 0x01, 0xFF, 0xFF, 0x80, 0x1F, 0xFF, 0xF8, + 0x01, 0xFF, 0xFF, 0x80, 0x1F, 0xFF, 0xF8, 0x01, 0xFF, 0xFF, 0x80, 0x1F, + 0xFF, 0xF8, 0x01, 0xFF, 0xFF, 0x80, 0x1F, 0xFF, 0xF8, 0x01, 0xFF, 0xFF, + 0x80, 0x1F, 0xFF, 0xF8, 0x01, 0xFF, 0xFF, 0x80, 0x1F, 0xFF, 0xF8, 0x01, + 0xFF, 0xFF, 0x80, 0x3F, 0xEF, 0xF8, 0x03, 0xFE, 0xFF, 0x80, 0x7F, 0xEF, + 0xF8, 0x0F, 0xFC, 0xFF, 0xFF, 0xFF, 0xCF, 0xFF, 0xFF, 0xFC, 0xFF, 0xFF, + 0xFF, 0x8F, 0xFF, 0xFF, 0xF0, 0xFF, 0xFF, 0xFE, 0x0F, 0xFF, 0xFF, 0xC0, + 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x7F, 0xC0, 0x00, 0x3F, 0xFE, 0x00, 0x1F, + 0xFF, 0xF0, 0x07, 0xFF, 0xFF, 0x01, 0xFF, 0xFF, 0xF0, 0x7F, 0xFF, 0xFE, + 0x0F, 0xFF, 0xFF, 0xE3, 0xFF, 0xFF, 0xFC, 0x7F, 0xE0, 0xFF, 0xCF, 0xF8, + 0x0F, 0xFB, 0xFE, 0x01, 0xFF, 0x7F, 0xC0, 0x1F, 0xEF, 0xF8, 0x03, 0xFF, + 0xFF, 0x00, 0x7F, 0xFF, 0xE0, 0x0F, 0xFF, 0xFC, 0x01, 0xFF, 0xFF, 0x00, + 0x3F, 0xFF, 0xE0, 0x07, 0xFF, 0xFC, 0x00, 0xFF, 0xFF, 0x80, 0x1F, 0xFF, + 0xF0, 0x03, 0xFF, 0xFE, 0x00, 0x7F, 0xFF, 0xC0, 0x0F, 0xFF, 0xF8, 0x01, + 0xFF, 0xFF, 0x00, 0x3F, 0xFF, 0xE0, 0x07, 0xFF, 0xFC, 0x00, 0xFF, 0xFF, + 0x80, 0x00, 0x0F, 0xF0, 0x00, 0x01, 0xFE, 0x00, 0x00, 0x3F, 0xC0, 0x00, + 0x07, 0xF8, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x1F, 0xE0, 0x00, 0x03, 0xFC, + 0x00, 0x00, 0x7F, 0x80, 0x00, 0x0F, 0xF0, 0x00, 0x01, 0xFE, 0x00, 0x00, + 0x3F, 0xC0, 0x00, 0x07, 0xF8, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x1F, 0xE0, + 0x07, 0xFF, 0xFC, 0x00, 0xFF, 0xFF, 0x80, 0x1F, 0xFF, 0xF0, 0x03, 0xFF, + 0xFE, 0x00, 0x7F, 0xFF, 0xC0, 0x0F, 0xFF, 0xF8, 0x01, 0xFF, 0xFF, 0x00, + 0x3F, 0xFF, 0xE0, 0x07, 0xFF, 0xFC, 0x00, 0xFF, 0xFF, 0x80, 0x1F, 0xFF, + 0xF0, 0x03, 0xFF, 0xFF, 0x00, 0x7F, 0xFF, 0xE0, 0x0F, 0xFF, 0xFC, 0x01, + 0xFF, 0xFF, 0x80, 0x3F, 0xDF, 0xF0, 0x07, 0xF9, 0xFE, 0x01, 0xFF, 0x3F, + 0xE0, 0x3F, 0xE7, 0xFE, 0x0F, 0xFC, 0x7F, 0xFF, 0xFF, 0x0F, 0xFF, 0xFF, + 0xE0, 0xFF, 0xFF, 0xF8, 0x1F, 0xFF, 0xFE, 0x01, 0xFF, 0xFF, 0xC0, 0x1F, + 0xFF, 0xF0, 0x00, 0xFF, 0xF8, 0x00, 0x03, 0xF8, 0x00, 0xFF, 0xFF, 0xF0, + 0x0F, 0xFF, 0xFF, 0xC0, 0xFF, 0xFF, 0xFE, 0x0F, 0xFF, 0xFF, 0xF0, 0xFF, + 0xFF, 0xFF, 0x8F, 0xFF, 0xFF, 0xF8, 0xFF, 0xFF, 0xFF, 0xCF, 0xF8, 0x0F, + 0xFC, 0xFF, 0x80, 0x7F, 0xEF, 0xF8, 0x03, 0xFE, 0xFF, 0x80, 0x3F, 0xEF, + 0xF8, 0x03, 0xFE, 0xFF, 0x80, 0x1F, 0xEF, 0xF8, 0x01, 0xFF, 0xFF, 0x80, + 0x1F, 0xFF, 0xF8, 0x01, 0xFF, 0xFF, 0x80, 0x1F, 0xFF, 0xF8, 0x01, 0xFF, + 0xFF, 0x80, 0x1F, 0xFF, 0xF8, 0x01, 0xFF, 0xFF, 0x80, 0x1F, 0xFF, 0xF8, + 0x01, 0xFF, 0xFF, 0x80, 0x1F, 0xFF, 0xF8, 0x01, 0xFF, 0xFF, 0x80, 0x1F, + 0xFF, 0xF8, 0x01, 0xFF, 0xFF, 0x80, 0x1F, 0xFF, 0xF8, 0x01, 0xFF, 0xFF, + 0x80, 0x1F, 0xFF, 0xF8, 0x01, 0xFF, 0xFF, 0x80, 0x1F, 0xFF, 0xF8, 0x01, + 0xFF, 0xFF, 0x80, 0x1F, 0xFF, 0xF8, 0x01, 0xFF, 0xFF, 0x80, 0x1F, 0xFF, + 0xF8, 0x01, 0xFF, 0xFF, 0x80, 0x1F, 0xFF, 0xF8, 0x01, 0xFF, 0xFF, 0x80, + 0x1F, 0xFF, 0xF8, 0x01, 0xFF, 0xFF, 0x80, 0x1F, 0xFF, 0xF8, 0x01, 0xFF, + 0xFF, 0x80, 0x1F, 0xFF, 0xF8, 0x01, 0xFF, 0xFF, 0x80, 0x1F, 0xFF, 0xF8, + 0x01, 0xFF, 0xFF, 0x80, 0x1F, 0xFF, 0xF8, 0x01, 0xFF, 0xFF, 0x80, 0x1F, + 0xFF, 0xF8, 0x01, 0xFF, 0xFF, 0x80, 0x1F, 0xFF, 0xF8, 0x01, 0xFF, 0xFF, + 0x80, 0x1F, 0xFF, 0xF8, 0x01, 0xFE, 0xFF, 0x80, 0x1F, 0xEF, 0xF8, 0x03, + 0xFE, 0xFF, 0x80, 0x3F, 0xEF, 0xF8, 0x03, 0xFE, 0xFF, 0x80, 0x7F, 0xCF, + 0xF8, 0x0F, 0xFC, 0xFF, 0xFF, 0xFF, 0xCF, 0xFF, 0xFF, 0xF8, 0xFF, 0xFF, + 0xFF, 0x0F, 0xFF, 0xFF, 0xF0, 0xFF, 0xFF, 0xFC, 0x0F, 0xFF, 0xFF, 0x80, + 0xFF, 0xFF, 0xC0, 0x00, 0xFF, 0xFF, 0xFB, 0xFF, 0xFF, 0xEF, 0xFF, 0xFF, + 0xBF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFB, 0xFF, 0xFF, 0xEF, 0xFF, 0xFF, 0xBF, + 0xE0, 0x00, 0xFF, 0x80, 0x03, 0xFE, 0x00, 0x0F, 0xF8, 0x00, 0x3F, 0xE0, + 0x00, 0xFF, 0x80, 0x03, 0xFE, 0x00, 0x0F, 0xF8, 0x00, 0x3F, 0xE0, 0x00, + 0xFF, 0x80, 0x03, 0xFE, 0x00, 0x0F, 0xF8, 0x00, 0x3F, 0xE0, 0x00, 0xFF, + 0x80, 0x03, 0xFE, 0x00, 0x0F, 0xF8, 0x00, 0x3F, 0xE0, 0x00, 0xFF, 0x80, + 0x03, 0xFE, 0x00, 0x0F, 0xF8, 0x00, 0x3F, 0xE0, 0x00, 0xFF, 0x80, 0x03, + 0xFF, 0xFF, 0xEF, 0xFF, 0xFF, 0xBF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFB, 0xFF, + 0xFF, 0xEF, 0xFF, 0xFF, 0xBF, 0xFF, 0xFE, 0xFF, 0x80, 0x03, 0xFE, 0x00, + 0x0F, 0xF8, 0x00, 0x3F, 0xE0, 0x00, 0xFF, 0x80, 0x03, 0xFE, 0x00, 0x0F, + 0xF8, 0x00, 0x3F, 0xE0, 0x00, 0xFF, 0x80, 0x03, 0xFE, 0x00, 0x0F, 0xF8, + 0x00, 0x3F, 0xE0, 0x00, 0xFF, 0x80, 0x03, 0xFE, 0x00, 0x0F, 0xF8, 0x00, + 0x3F, 0xE0, 0x00, 0xFF, 0x80, 0x03, 0xFE, 0x00, 0x0F, 0xF8, 0x00, 0x3F, + 0xE0, 0x00, 0xFF, 0x80, 0x03, 0xFE, 0x00, 0x0F, 0xF8, 0x00, 0x3F, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0x00, 0xFF, 0x80, 0x03, 0xFE, 0x00, + 0x0F, 0xF8, 0x00, 0x3F, 0xE0, 0x00, 0xFF, 0x80, 0x03, 0xFE, 0x00, 0x0F, + 0xF8, 0x00, 0x3F, 0xE0, 0x00, 0xFF, 0x80, 0x03, 0xFE, 0x00, 0x0F, 0xF8, + 0x00, 0x3F, 0xE0, 0x00, 0xFF, 0x80, 0x03, 0xFE, 0x00, 0x0F, 0xF8, 0x00, + 0x3F, 0xE0, 0x00, 0xFF, 0x80, 0x03, 0xFE, 0x00, 0x0F, 0xF8, 0x00, 0x3F, + 0xFF, 0xFE, 0xFF, 0xFF, 0xFB, 0xFF, 0xFF, 0xEF, 0xFF, 0xFF, 0xBF, 0xFF, + 0xFE, 0xFF, 0xFF, 0xFB, 0xFF, 0xFF, 0xEF, 0xFF, 0xFF, 0xBF, 0xE0, 0x00, + 0xFF, 0x80, 0x03, 0xFE, 0x00, 0x0F, 0xF8, 0x00, 0x3F, 0xE0, 0x00, 0xFF, + 0x80, 0x03, 0xFE, 0x00, 0x0F, 0xF8, 0x00, 0x3F, 0xE0, 0x00, 0xFF, 0x80, + 0x03, 0xFE, 0x00, 0x0F, 0xF8, 0x00, 0x3F, 0xE0, 0x00, 0xFF, 0x80, 0x03, + 0xFE, 0x00, 0x0F, 0xF8, 0x00, 0x3F, 0xE0, 0x00, 0xFF, 0x80, 0x03, 0xFE, + 0x00, 0x0F, 0xF8, 0x00, 0x3F, 0xE0, 0x00, 0xFF, 0x80, 0x03, 0xFE, 0x00, + 0x0F, 0xF8, 0x00, 0x3F, 0xE0, 0x00, 0xFF, 0x80, 0x03, 0xFE, 0x00, 0x0F, + 0xF8, 0x00, 0x3F, 0xE0, 0x00, 0xFF, 0x80, 0x03, 0xFE, 0x00, 0x0F, 0xF8, + 0x00, 0x00, 0x00, 0x7F, 0xE0, 0x00, 0x3F, 0xFF, 0x00, 0x1F, 0xFF, 0xF8, + 0x07, 0xFF, 0xFF, 0x81, 0xFF, 0xFF, 0xF0, 0x7F, 0xFF, 0xFF, 0x0F, 0xFF, + 0xFF, 0xE3, 0xFF, 0xFF, 0xFE, 0x7F, 0xE0, 0x7F, 0xCF, 0xF8, 0x07, 0xFB, + 0xFE, 0x00, 0xFF, 0xFF, 0xC0, 0x1F, 0xFF, 0xF8, 0x03, 0xFF, 0xFF, 0x00, + 0x3F, 0xFF, 0xE0, 0x07, 0xFF, 0xFC, 0x00, 0xFF, 0xFF, 0x00, 0x1F, 0xFF, + 0xE0, 0x03, 0xFF, 0xFC, 0x00, 0x7F, 0xFF, 0x80, 0x0F, 0xFF, 0xF0, 0x01, + 0xFF, 0xFE, 0x00, 0x3F, 0xFF, 0xC0, 0x07, 0xFF, 0xF8, 0x00, 0xFF, 0xFF, + 0x00, 0x1F, 0xFF, 0xE0, 0x00, 0x03, 0xFC, 0x00, 0x00, 0x7F, 0x80, 0x00, + 0x0F, 0xF0, 0x00, 0x01, 0xFE, 0x00, 0x00, 0x3F, 0xC0, 0x00, 0x07, 0xF8, + 0x00, 0x00, 0xFF, 0x03, 0xFF, 0xFF, 0xE0, 0x7F, 0xFF, 0xFC, 0x0F, 0xFF, + 0xFF, 0x81, 0xFF, 0xFF, 0xF0, 0x3F, 0xFF, 0xFE, 0x07, 0xFF, 0xFF, 0xC0, + 0xFF, 0xFF, 0xF8, 0x00, 0xFF, 0xFF, 0x00, 0x1F, 0xFF, 0xE0, 0x03, 0xFF, + 0xFC, 0x00, 0x7F, 0xFF, 0x80, 0x0F, 0xFF, 0xF0, 0x01, 0xFF, 0xFE, 0x00, + 0x3F, 0xFF, 0xC0, 0x07, 0xFF, 0xF8, 0x00, 0xFF, 0xFF, 0x00, 0x1F, 0xFF, + 0xE0, 0x03, 0xFF, 0xFC, 0x00, 0x7F, 0xFF, 0x80, 0x0F, 0xFF, 0xF8, 0x01, + 0xFF, 0xFF, 0x00, 0x3F, 0xFF, 0xE0, 0x07, 0xFF, 0xFC, 0x00, 0xFF, 0xFF, + 0x80, 0x3F, 0xFF, 0xF0, 0x07, 0xFD, 0xFF, 0x00, 0xFF, 0xBF, 0xE0, 0x3F, + 0xF7, 0xFE, 0x0F, 0xFE, 0x7F, 0xFF, 0xFF, 0xCF, 0xFF, 0xFE, 0xF8, 0xFF, + 0xFF, 0xDF, 0x1F, 0xFF, 0xF3, 0xE1, 0xFF, 0xFE, 0x7C, 0x1F, 0xFF, 0x8F, + 0x80, 0xFF, 0xC0, 0xF0, 0x01, 0x80, 0x00, 0xFF, 0x80, 0x1F, 0xFF, 0xF8, + 0x01, 0xFF, 0xFF, 0x80, 0x1F, 0xFF, 0xF8, 0x01, 0xFF, 0xFF, 0x80, 0x1F, + 0xFF, 0xF8, 0x01, 0xFF, 0xFF, 0x80, 0x1F, 0xFF, 0xF8, 0x01, 0xFF, 0xFF, + 0x80, 0x1F, 0xFF, 0xF8, 0x01, 0xFF, 0xFF, 0x80, 0x1F, 0xFF, 0xF8, 0x01, + 0xFF, 0xFF, 0x80, 0x1F, 0xFF, 0xF8, 0x01, 0xFF, 0xFF, 0x80, 0x1F, 0xFF, + 0xF8, 0x01, 0xFF, 0xFF, 0x80, 0x1F, 0xFF, 0xF8, 0x01, 0xFF, 0xFF, 0x80, + 0x1F, 0xFF, 0xF8, 0x01, 0xFF, 0xFF, 0x80, 0x1F, 0xFF, 0xF8, 0x01, 0xFF, + 0xFF, 0x80, 0x1F, 0xFF, 0xF8, 0x01, 0xFF, 0xFF, 0x80, 0x1F, 0xFF, 0xF8, + 0x01, 0xFF, 0xFF, 0x80, 0x1F, 0xFF, 0xF8, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x01, + 0xFF, 0xFF, 0x80, 0x1F, 0xFF, 0xF8, 0x01, 0xFF, 0xFF, 0x80, 0x1F, 0xFF, + 0xF8, 0x01, 0xFF, 0xFF, 0x80, 0x1F, 0xFF, 0xF8, 0x01, 0xFF, 0xFF, 0x80, + 0x1F, 0xFF, 0xF8, 0x01, 0xFF, 0xFF, 0x80, 0x1F, 0xFF, 0xF8, 0x01, 0xFF, + 0xFF, 0x80, 0x1F, 0xFF, 0xF8, 0x01, 0xFF, 0xFF, 0x80, 0x1F, 0xFF, 0xF8, + 0x01, 0xFF, 0xFF, 0x80, 0x1F, 0xFF, 0xF8, 0x01, 0xFF, 0xFF, 0x80, 0x1F, + 0xFF, 0xF8, 0x01, 0xFF, 0xFF, 0x80, 0x1F, 0xFF, 0xF8, 0x01, 0xFF, 0xFF, + 0x80, 0x1F, 0xFF, 0xF8, 0x01, 0xFF, 0xFF, 0x80, 0x1F, 0xFF, 0xF8, 0x01, + 0xFF, 0xFF, 0x80, 0x1F, 0xFF, 0xF8, 0x01, 0xFF, 0xFF, 0x80, 0x1F, 0xFF, + 0xF8, 0x01, 0xFF, 0xFF, 0x80, 0x1F, 0xFF, 0xF8, 0x01, 0xFF, 0xFF, 0x80, + 0x1F, 0xF0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x7F, 0xC0, 0x00, 0x1F, + 0xF0, 0x00, 0x07, 0xFC, 0x00, 0x01, 0xFF, 0x00, 0x00, 0x7F, 0xC0, 0x00, + 0x1F, 0xF0, 0x00, 0x07, 0xFC, 0x00, 0x01, 0xFF, 0x00, 0x00, 0x7F, 0xC0, + 0x00, 0x1F, 0xF0, 0x00, 0x07, 0xFC, 0x00, 0x01, 0xFF, 0x00, 0x00, 0x7F, + 0xC0, 0x00, 0x1F, 0xF0, 0x00, 0x07, 0xFC, 0x00, 0x01, 0xFF, 0x00, 0x00, + 0x7F, 0xC0, 0x00, 0x1F, 0xF0, 0x00, 0x07, 0xFC, 0x00, 0x01, 0xFF, 0x00, + 0x00, 0x7F, 0xC0, 0x00, 0x1F, 0xF0, 0x00, 0x07, 0xFC, 0x00, 0x01, 0xFF, + 0x00, 0x00, 0x7F, 0xC0, 0x00, 0x1F, 0xF0, 0x00, 0x07, 0xFC, 0x00, 0x01, + 0xFF, 0x00, 0x00, 0x7F, 0xC0, 0x00, 0x1F, 0xF0, 0x00, 0x07, 0xFC, 0x00, + 0x01, 0xFF, 0x00, 0x00, 0x7F, 0xC0, 0x00, 0x1F, 0xF0, 0x00, 0x07, 0xFC, + 0x00, 0x01, 0xFF, 0x00, 0x00, 0x7F, 0xC0, 0x00, 0x1F, 0xF0, 0x00, 0x07, + 0xFC, 0x00, 0x01, 0xFF, 0x00, 0x00, 0x7F, 0xC0, 0x00, 0x1F, 0xFF, 0xF8, + 0x07, 0xFF, 0xFE, 0x01, 0xFF, 0xFF, 0x80, 0x7F, 0xFF, 0xE0, 0x1F, 0xFF, + 0xF8, 0x07, 0xFF, 0xFE, 0x01, 0xFF, 0xFF, 0x80, 0x7F, 0xFF, 0xE0, 0x1F, + 0xFF, 0xF8, 0x07, 0xFF, 0xFE, 0x01, 0xFF, 0xFF, 0x80, 0x7F, 0xFF, 0xE0, + 0x1F, 0xFF, 0xF8, 0x07, 0xFF, 0xFE, 0x01, 0xFF, 0x7F, 0x80, 0x7F, 0xDF, + 0xF0, 0x1F, 0xE7, 0xFC, 0x0F, 0xF9, 0xFF, 0x87, 0xFE, 0x3F, 0xFF, 0xFF, + 0x0F, 0xFF, 0xFF, 0xC1, 0xFF, 0xFF, 0xE0, 0x7F, 0xFF, 0xF8, 0x0F, 0xFF, + 0xFC, 0x01, 0xFF, 0xFE, 0x00, 0x1F, 0xFE, 0x00, 0x00, 0xFC, 0x00, 0xFF, + 0x80, 0x0F, 0xFF, 0xFE, 0x00, 0x3F, 0xEF, 0xF8, 0x01, 0xFF, 0x3F, 0xE0, + 0x07, 0xFC, 0xFF, 0x80, 0x1F, 0xF3, 0xFE, 0x00, 0xFF, 0x8F, 0xF8, 0x03, + 0xFE, 0x3F, 0xE0, 0x0F, 0xF8, 0xFF, 0x80, 0x7F, 0xC3, 0xFE, 0x01, 0xFF, + 0x0F, 0xF8, 0x07, 0xFC, 0x3F, 0xE0, 0x3F, 0xE0, 0xFF, 0x80, 0xFF, 0x83, + 0xFE, 0x03, 0xFE, 0x0F, 0xF8, 0x1F, 0xF0, 0x3F, 0xE0, 0x7F, 0xC0, 0xFF, + 0x83, 0xFE, 0x03, 0xFE, 0x0F, 0xF8, 0x0F, 0xF8, 0x3F, 0xE0, 0x3F, 0xE1, + 0xFF, 0x00, 0xFF, 0x87, 0xFC, 0x03, 0xFE, 0x1F, 0xF0, 0x0F, 0xF8, 0xFF, + 0x80, 0x3F, 0xE3, 0xFE, 0x00, 0xFF, 0x8F, 0xF8, 0x03, 0xFE, 0x7F, 0xC0, + 0x0F, 0xF9, 0xFF, 0x00, 0x3F, 0xE7, 0xF8, 0x00, 0xFF, 0xBF, 0xE0, 0x03, + 0xFE, 0xFF, 0x80, 0x0F, 0xFF, 0xFC, 0x00, 0x3F, 0xFF, 0xF0, 0x00, 0xFF, + 0xFF, 0xC0, 0x03, 0xFF, 0xFF, 0x00, 0x0F, 0xFF, 0xFC, 0x00, 0x3F, 0xFF, + 0xF8, 0x00, 0xFF, 0xBF, 0xE0, 0x03, 0xFE, 0xFF, 0x80, 0x0F, 0xF9, 0xFF, + 0x00, 0x3F, 0xE7, 0xFC, 0x00, 0xFF, 0x9F, 0xF0, 0x03, 0xFE, 0x3F, 0xE0, + 0x0F, 0xF8, 0xFF, 0x80, 0x3F, 0xE3, 0xFF, 0x00, 0xFF, 0x87, 0xFC, 0x03, + 0xFE, 0x1F, 0xF0, 0x0F, 0xF8, 0x7F, 0xE0, 0x3F, 0xE0, 0xFF, 0x80, 0xFF, + 0x83, 0xFE, 0x03, 0xFE, 0x07, 0xFC, 0x0F, 0xF8, 0x1F, 0xF0, 0x3F, 0xE0, + 0x7F, 0xE0, 0xFF, 0x80, 0xFF, 0x83, 0xFE, 0x03, 0xFE, 0x0F, 0xF8, 0x0F, + 0xFC, 0x3F, 0xE0, 0x1F, 0xF0, 0xFF, 0x80, 0x7F, 0xC3, 0xFE, 0x00, 0xFF, + 0x8F, 0xF8, 0x03, 0xFE, 0x3F, 0xE0, 0x0F, 0xFC, 0xFF, 0x80, 0x1F, 0xF3, + 0xFE, 0x00, 0x7F, 0xCF, 0xF8, 0x01, 0xFF, 0xBF, 0xE0, 0x03, 0xFE, 0xFF, + 0x80, 0x0F, 0xFB, 0xFE, 0x00, 0x1F, 0xFF, 0xF8, 0x00, 0x7F, 0xC0, 0xFF, + 0x80, 0x03, 0xFE, 0x00, 0x0F, 0xF8, 0x00, 0x3F, 0xE0, 0x00, 0xFF, 0x80, + 0x03, 0xFE, 0x00, 0x0F, 0xF8, 0x00, 0x3F, 0xE0, 0x00, 0xFF, 0x80, 0x03, + 0xFE, 0x00, 0x0F, 0xF8, 0x00, 0x3F, 0xE0, 0x00, 0xFF, 0x80, 0x03, 0xFE, + 0x00, 0x0F, 0xF8, 0x00, 0x3F, 0xE0, 0x00, 0xFF, 0x80, 0x03, 0xFE, 0x00, + 0x0F, 0xF8, 0x00, 0x3F, 0xE0, 0x00, 0xFF, 0x80, 0x03, 0xFE, 0x00, 0x0F, + 0xF8, 0x00, 0x3F, 0xE0, 0x00, 0xFF, 0x80, 0x03, 0xFE, 0x00, 0x0F, 0xF8, + 0x00, 0x3F, 0xE0, 0x00, 0xFF, 0x80, 0x03, 0xFE, 0x00, 0x0F, 0xF8, 0x00, + 0x3F, 0xE0, 0x00, 0xFF, 0x80, 0x03, 0xFE, 0x00, 0x0F, 0xF8, 0x00, 0x3F, + 0xE0, 0x00, 0xFF, 0x80, 0x03, 0xFE, 0x00, 0x0F, 0xF8, 0x00, 0x3F, 0xE0, + 0x00, 0xFF, 0x80, 0x03, 0xFE, 0x00, 0x0F, 0xF8, 0x00, 0x3F, 0xE0, 0x00, + 0xFF, 0x80, 0x03, 0xFE, 0x00, 0x0F, 0xF8, 0x00, 0x3F, 0xE0, 0x00, 0xFF, + 0x80, 0x03, 0xFE, 0x00, 0x0F, 0xF8, 0x00, 0x3F, 0xE0, 0x00, 0xFF, 0x80, + 0x03, 0xFE, 0x00, 0x0F, 0xF8, 0x00, 0x3F, 0xE0, 0x00, 0xFF, 0x80, 0x03, + 0xFE, 0x00, 0x0F, 0xF8, 0x00, 0x3F, 0xE0, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xC0, 0xFF, 0xE0, 0x00, 0x03, 0xFF, 0xFF, 0xF0, 0x00, + 0x01, 0xFF, 0xFF, 0xF8, 0x00, 0x00, 0xFF, 0xFF, 0xFE, 0x00, 0x00, 0x7F, + 0xFF, 0xFF, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0x80, 0x00, 0x3F, 0xFF, 0xFF, + 0xC0, 0x00, 0x1F, 0xFF, 0xFF, 0xE0, 0x00, 0x0F, 0xFF, 0xFF, 0xF8, 0x00, + 0x07, 0xFF, 0xFF, 0xFC, 0x00, 0x03, 0xFF, 0xFF, 0xFE, 0x00, 0x03, 0xFF, + 0xFF, 0xFF, 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0xFF, 0xFF, 0xFF, + 0xE0, 0x00, 0x7F, 0xFF, 0xFF, 0xF0, 0x00, 0x3F, 0xFF, 0xFF, 0xF8, 0x00, + 0x1F, 0xFF, 0xFF, 0xFC, 0x00, 0x1F, 0xFF, 0xFF, 0xFE, 0x00, 0x0F, 0xFF, + 0xFF, 0xBF, 0x80, 0x07, 0xFF, 0xFF, 0xFF, 0xC0, 0x03, 0xFF, 0xFF, 0xFF, + 0xE0, 0x01, 0xFB, 0xFF, 0xFF, 0xF0, 0x01, 0xFD, 0xFF, 0xFD, 0xF8, 0x00, + 0xFE, 0xFF, 0xFE, 0xFE, 0x00, 0x7F, 0x7F, 0xFF, 0x7F, 0x00, 0x3F, 0xBF, + 0xFF, 0xBF, 0x80, 0x1F, 0x9F, 0xFF, 0xDF, 0xC0, 0x0F, 0xCF, 0xFF, 0xE7, + 0xE0, 0x0F, 0xE7, 0xFF, 0xF3, 0xF8, 0x07, 0xF3, 0xFF, 0xF9, 0xFC, 0x03, + 0xF9, 0xFF, 0xFC, 0xFE, 0x01, 0xF8, 0xFF, 0xFE, 0x7F, 0x00, 0xFC, 0x7F, + 0xFF, 0x1F, 0x80, 0xFE, 0x3F, 0xFF, 0x8F, 0xC0, 0x7F, 0x1F, 0xFF, 0xC7, + 0xF0, 0x3F, 0x8F, 0xFF, 0xE3, 0xF8, 0x1F, 0x87, 0xFF, 0xF1, 0xFC, 0x0F, + 0xC3, 0xFF, 0xF8, 0x7E, 0x07, 0xE1, 0xFF, 0xFC, 0x3F, 0x07, 0xF1, 0xFF, + 0xFE, 0x1F, 0xC3, 0xF8, 0xFF, 0xFF, 0x0F, 0xE1, 0xF8, 0x7F, 0xFF, 0x87, + 0xF0, 0xFC, 0x3F, 0xFF, 0xC1, 0xF8, 0x7E, 0x1F, 0xFF, 0xE0, 0xFC, 0x7F, + 0x0F, 0xFF, 0xF0, 0x7F, 0x3F, 0x87, 0xFF, 0xF8, 0x3F, 0x9F, 0x83, 0xFF, + 0xFC, 0x1F, 0xCF, 0xC1, 0xFF, 0xFE, 0x07, 0xE7, 0xE0, 0xFF, 0xFF, 0x03, + 0xF3, 0xF0, 0x7F, 0xFF, 0x81, 0xFF, 0xF8, 0x3F, 0xFF, 0xC0, 0xFF, 0xF8, + 0x1F, 0xFF, 0xE0, 0x7F, 0xFC, 0x0F, 0xFF, 0xF0, 0x1F, 0xFE, 0x07, 0xFF, + 0xF8, 0x0F, 0xFF, 0x03, 0xFF, 0xFC, 0x07, 0xFF, 0x81, 0xFF, 0xFE, 0x03, + 0xFF, 0xC0, 0xFF, 0xFF, 0x01, 0xFF, 0xC0, 0x7F, 0xFF, 0x80, 0x7F, 0xE0, + 0x3F, 0xFF, 0xC0, 0x3F, 0xF0, 0x1F, 0xFF, 0xE0, 0x1F, 0xF8, 0x0F, 0xFF, + 0xF0, 0x0F, 0xFC, 0x07, 0xFF, 0xF8, 0x07, 0xFC, 0x03, 0xFF, 0xFC, 0x01, + 0xFE, 0x01, 0xFF, 0xFE, 0x00, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0x7F, 0x80, + 0x7F, 0xFF, 0x80, 0x3F, 0xC0, 0x3F, 0xFF, 0xC0, 0x1F, 0xC0, 0x1F, 0xE0, + 0xFE, 0x00, 0x07, 0xFF, 0xF8, 0x00, 0x3F, 0xFF, 0xC0, 0x01, 0xFF, 0xFE, + 0x00, 0x0F, 0xFF, 0xF8, 0x00, 0x7F, 0xFF, 0xC0, 0x03, 0xFF, 0xFF, 0x00, + 0x1F, 0xFF, 0xF8, 0x00, 0xFF, 0xFF, 0xC0, 0x07, 0xFF, 0xFF, 0x00, 0x3F, + 0xFF, 0xF8, 0x01, 0xFF, 0xFF, 0xC0, 0x0F, 0xFF, 0xFF, 0x00, 0x7F, 0xFF, + 0xF8, 0x03, 0xFF, 0xFF, 0xC0, 0x1F, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xF8, + 0x07, 0xFF, 0xFF, 0xC0, 0x3F, 0xFF, 0xFF, 0x01, 0xFF, 0xFF, 0xF8, 0x0F, + 0xFF, 0xFF, 0xC0, 0x7F, 0xFF, 0xFF, 0x03, 0xFF, 0xFF, 0xF8, 0x1F, 0xFF, + 0xFF, 0xC0, 0xFF, 0xFF, 0x7F, 0x07, 0xFF, 0xFB, 0xF8, 0x3F, 0xFF, 0xDF, + 0xC0, 0xFF, 0xFE, 0x7F, 0x07, 0xFF, 0xF3, 0xF8, 0x3F, 0xFF, 0x9F, 0xC1, + 0xFF, 0xFC, 0x7F, 0x0F, 0xFF, 0xE3, 0xF8, 0x7F, 0xFF, 0x1F, 0xC3, 0xFF, + 0xF8, 0x7F, 0x1F, 0xFF, 0xC3, 0xF8, 0xFF, 0xFE, 0x1F, 0xE7, 0xFF, 0xF0, + 0x7F, 0x3F, 0xFF, 0x83, 0xF9, 0xFF, 0xFC, 0x1F, 0xEF, 0xFF, 0xE0, 0x7F, + 0x7F, 0xFF, 0x83, 0xFB, 0xFF, 0xFC, 0x1F, 0xFF, 0xFF, 0xE0, 0x7F, 0xFF, + 0xFF, 0x03, 0xFF, 0xFF, 0xF8, 0x1F, 0xFF, 0xFF, 0xC0, 0x7F, 0xFF, 0xFE, + 0x03, 0xFF, 0xFF, 0xF0, 0x1F, 0xFF, 0xFF, 0x80, 0x7F, 0xFF, 0xFC, 0x03, + 0xFF, 0xFF, 0xE0, 0x1F, 0xFF, 0xFF, 0x00, 0x7F, 0xFF, 0xF8, 0x03, 0xFF, + 0xFF, 0xC0, 0x1F, 0xFF, 0xFE, 0x00, 0x7F, 0xFF, 0xF0, 0x03, 0xFF, 0xFF, + 0x80, 0x1F, 0xFF, 0xFC, 0x00, 0x7F, 0xFF, 0xE0, 0x03, 0xFF, 0xFF, 0x00, + 0x1F, 0xFF, 0xF8, 0x00, 0x7F, 0xFF, 0xC0, 0x03, 0xFF, 0xFE, 0x00, 0x1F, + 0xFF, 0xF0, 0x00, 0x7F, 0xFF, 0x80, 0x03, 0xFF, 0xFC, 0x00, 0x1F, 0xFF, + 0xE0, 0x00, 0x7E, 0x00, 0x7F, 0xE0, 0x00, 0x7F, 0xFF, 0x00, 0x1F, 0xFF, + 0xF8, 0x07, 0xFF, 0xFF, 0x81, 0xFF, 0xFF, 0xF0, 0x7F, 0xFF, 0xFF, 0x0F, + 0xFF, 0xFF, 0xE3, 0xFF, 0xFF, 0xFE, 0x7F, 0xE0, 0x7F, 0xCF, 0xF8, 0x0F, + 0xFB, 0xFE, 0x00, 0xFF, 0xFF, 0xC0, 0x1F, 0xFF, 0xF8, 0x03, 0xFF, 0xFF, + 0x00, 0x7F, 0xFF, 0xE0, 0x0F, 0xFF, 0xFC, 0x01, 0xFF, 0xFF, 0x00, 0x1F, + 0xFF, 0xE0, 0x03, 0xFF, 0xFC, 0x00, 0x7F, 0xFF, 0x80, 0x0F, 0xFF, 0xF0, + 0x01, 0xFF, 0xFE, 0x00, 0x3F, 0xFF, 0xC0, 0x07, 0xFF, 0xF8, 0x00, 0xFF, + 0xFF, 0x00, 0x1F, 0xFF, 0xE0, 0x03, 0xFF, 0xFC, 0x00, 0x7F, 0xFF, 0x80, + 0x0F, 0xFF, 0xF0, 0x01, 0xFF, 0xFE, 0x00, 0x3F, 0xFF, 0xC0, 0x07, 0xFF, + 0xF8, 0x00, 0xFF, 0xFF, 0x00, 0x1F, 0xFF, 0xE0, 0x03, 0xFF, 0xFC, 0x00, + 0x7F, 0xFF, 0x80, 0x0F, 0xFF, 0xF0, 0x01, 0xFF, 0xFE, 0x00, 0x3F, 0xFF, + 0xC0, 0x07, 0xFF, 0xF8, 0x00, 0xFF, 0xFF, 0x00, 0x1F, 0xFF, 0xE0, 0x03, + 0xFF, 0xFC, 0x00, 0x7F, 0xFF, 0x80, 0x0F, 0xFF, 0xF0, 0x01, 0xFF, 0xFE, + 0x00, 0x3F, 0xFF, 0xC0, 0x07, 0xFF, 0xF8, 0x00, 0xFF, 0xFF, 0x00, 0x1F, + 0xFF, 0xE0, 0x03, 0xFF, 0xFC, 0x00, 0x7F, 0xFF, 0x80, 0x1F, 0xFF, 0xF0, + 0x03, 0xFF, 0xFF, 0x00, 0x7F, 0xFF, 0xE0, 0x0F, 0xFF, 0xFC, 0x01, 0xFF, + 0xFF, 0x80, 0x3F, 0xFF, 0xF0, 0x07, 0xFF, 0xFE, 0x00, 0xFF, 0xBF, 0xE0, + 0x3F, 0xE7, 0xFE, 0x0F, 0xFC, 0xFF, 0xFF, 0xFF, 0x8F, 0xFF, 0xFF, 0xE1, + 0xFF, 0xFF, 0xFC, 0x1F, 0xFF, 0xFF, 0x01, 0xFF, 0xFF, 0xC0, 0x1F, 0xFF, + 0xF0, 0x00, 0xFF, 0xF8, 0x00, 0x03, 0xF8, 0x00, 0xFF, 0xFF, 0xF0, 0x0F, + 0xFF, 0xFF, 0xC0, 0xFF, 0xFF, 0xFE, 0x0F, 0xFF, 0xFF, 0xF0, 0xFF, 0xFF, + 0xFF, 0x8F, 0xFF, 0xFF, 0xFC, 0xFF, 0xFF, 0xFF, 0xCF, 0xF8, 0x0F, 0xFC, + 0xFF, 0x80, 0x7F, 0xEF, 0xF8, 0x03, 0xFE, 0xFF, 0x80, 0x3F, 0xEF, 0xF8, + 0x03, 0xFE, 0xFF, 0x80, 0x1F, 0xEF, 0xF8, 0x01, 0xFE, 0xFF, 0x80, 0x1F, + 0xFF, 0xF8, 0x01, 0xFF, 0xFF, 0x80, 0x1F, 0xFF, 0xF8, 0x01, 0xFF, 0xFF, + 0x80, 0x1F, 0xFF, 0xF8, 0x01, 0xFF, 0xFF, 0x80, 0x1F, 0xFF, 0xF8, 0x01, + 0xFF, 0xFF, 0x80, 0x1F, 0xFF, 0xF8, 0x01, 0xFF, 0xFF, 0x80, 0x1F, 0xFF, + 0xF8, 0x01, 0xFF, 0xFF, 0x80, 0x1F, 0xEF, 0xF8, 0x01, 0xFE, 0xFF, 0x80, + 0x3F, 0xEF, 0xF8, 0x03, 0xFE, 0xFF, 0x80, 0x3F, 0xEF, 0xF8, 0x07, 0xFE, + 0xFF, 0x80, 0xFF, 0xCF, 0xFF, 0xFF, 0xFC, 0xFF, 0xFF, 0xFF, 0xCF, 0xFF, + 0xFF, 0xF8, 0xFF, 0xFF, 0xFF, 0x0F, 0xFF, 0xFF, 0xE0, 0xFF, 0xFF, 0xFC, + 0x0F, 0xFF, 0xFF, 0x80, 0xFF, 0xFE, 0x00, 0x0F, 0xF8, 0x00, 0x00, 0xFF, + 0x80, 0x00, 0x0F, 0xF8, 0x00, 0x00, 0xFF, 0x80, 0x00, 0x0F, 0xF8, 0x00, + 0x00, 0xFF, 0x80, 0x00, 0x0F, 0xF8, 0x00, 0x00, 0xFF, 0x80, 0x00, 0x0F, + 0xF8, 0x00, 0x00, 0xFF, 0x80, 0x00, 0x0F, 0xF8, 0x00, 0x00, 0xFF, 0x80, + 0x00, 0x0F, 0xF8, 0x00, 0x00, 0xFF, 0x80, 0x00, 0x0F, 0xF8, 0x00, 0x00, + 0xFF, 0x80, 0x00, 0x0F, 0xF8, 0x00, 0x00, 0xFF, 0x80, 0x00, 0x0F, 0xF8, + 0x00, 0x00, 0xFF, 0x80, 0x00, 0x0F, 0xF8, 0x00, 0x00, 0xFF, 0x80, 0x00, + 0x0F, 0xF8, 0x00, 0x00, 0xFF, 0x80, 0x00, 0x0F, 0xF8, 0x00, 0x00, 0xFF, + 0x80, 0x00, 0x00, 0x00, 0x7F, 0xE0, 0x00, 0x7F, 0xFF, 0x00, 0x1F, 0xFF, + 0xF8, 0x07, 0xFF, 0xFF, 0x81, 0xFF, 0xFF, 0xF0, 0x7F, 0xFF, 0xFF, 0x0F, + 0xFF, 0xFF, 0xE3, 0xFF, 0xFF, 0xFE, 0x7F, 0xE0, 0x7F, 0xCF, 0xF8, 0x0F, + 0xFB, 0xFE, 0x00, 0xFF, 0xFF, 0xC0, 0x1F, 0xFF, 0xF8, 0x03, 0xFF, 0xFF, + 0x00, 0x7F, 0xFF, 0xE0, 0x0F, 0xFF, 0xFC, 0x01, 0xFF, 0xFF, 0x00, 0x1F, + 0xFF, 0xE0, 0x03, 0xFF, 0xFC, 0x00, 0x7F, 0xFF, 0x80, 0x0F, 0xFF, 0xF0, + 0x01, 0xFF, 0xFE, 0x00, 0x3F, 0xFF, 0xC0, 0x07, 0xFF, 0xF8, 0x00, 0xFF, + 0xFF, 0x00, 0x1F, 0xFF, 0xE0, 0x03, 0xFF, 0xFC, 0x00, 0x7F, 0xFF, 0x80, + 0x0F, 0xFF, 0xF0, 0x01, 0xFF, 0xFE, 0x00, 0x3F, 0xFF, 0xC0, 0x07, 0xFF, + 0xF8, 0x00, 0xFF, 0xFF, 0x00, 0x1F, 0xFF, 0xE0, 0x03, 0xFF, 0xFC, 0x00, + 0x7F, 0xFF, 0x80, 0x0F, 0xFF, 0xF0, 0x01, 0xFF, 0xFE, 0x00, 0x3F, 0xFF, + 0xC0, 0x07, 0xFF, 0xF8, 0x00, 0xFF, 0xFF, 0x00, 0x1F, 0xFF, 0xE0, 0x03, + 0xFF, 0xFC, 0x00, 0x7F, 0xFF, 0x80, 0x0F, 0xFF, 0xF0, 0x01, 0xFF, 0xFE, + 0x00, 0x3F, 0xFF, 0xC0, 0x07, 0xFF, 0xF8, 0x00, 0xFF, 0xFF, 0x00, 0x1F, + 0xFF, 0xE0, 0x03, 0xFF, 0xFC, 0x00, 0x7F, 0xFF, 0x80, 0x1F, 0xFF, 0xF0, + 0x03, 0xFF, 0xFF, 0x00, 0x7F, 0xFF, 0xE0, 0x0F, 0xFF, 0xFC, 0x01, 0xFF, + 0xFF, 0x80, 0x3F, 0xFF, 0xF0, 0x07, 0xFF, 0xFE, 0x00, 0xFF, 0xBF, 0xE0, + 0x3F, 0xE7, 0xFE, 0x0F, 0xFC, 0xFF, 0xFF, 0xFF, 0x8F, 0xFF, 0xFF, 0xE1, + 0xFF, 0xFF, 0xFC, 0x1F, 0xFF, 0xFF, 0x01, 0xFF, 0xFF, 0xC0, 0x1F, 0xFF, + 0xF0, 0x00, 0xFF, 0xF8, 0x00, 0x03, 0xFF, 0x00, 0x00, 0x0F, 0xF0, 0x00, + 0x00, 0xFF, 0x00, 0x00, 0x0F, 0xF0, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x0F, + 0xF0, 0x00, 0x01, 0xFF, 0x00, 0x00, 0x1F, 0xC0, 0x00, 0x01, 0xF0, 0x00, + 0x00, 0x1C, 0x00, 0x00, 0x01, 0x00, 0xFF, 0xFF, 0xF8, 0x0F, 0xFF, 0xFF, + 0xE0, 0xFF, 0xFF, 0xFF, 0x0F, 0xFF, 0xFF, 0xF8, 0xFF, 0xFF, 0xFF, 0xCF, + 0xFF, 0xFF, 0xFC, 0xFF, 0xFF, 0xFF, 0xEF, 0xF8, 0x07, 0xFE, 0xFF, 0x80, + 0x3F, 0xEF, 0xF8, 0x03, 0xFE, 0xFF, 0x80, 0x1F, 0xEF, 0xF8, 0x01, 0xFE, + 0xFF, 0x80, 0x1F, 0xFF, 0xF8, 0x01, 0xFF, 0xFF, 0x80, 0x1F, 0xFF, 0xF8, + 0x01, 0xFF, 0xFF, 0x80, 0x1F, 0xFF, 0xF8, 0x01, 0xFF, 0xFF, 0x80, 0x1F, + 0xFF, 0xF8, 0x01, 0xFF, 0xFF, 0x80, 0x1F, 0xFF, 0xF8, 0x01, 0xFF, 0xFF, + 0x80, 0x1F, 0xEF, 0xF8, 0x01, 0xFE, 0xFF, 0x80, 0x3F, 0xEF, 0xF8, 0x03, + 0xFE, 0xFF, 0x80, 0x3F, 0xEF, 0xF8, 0x07, 0xFC, 0xFF, 0xFF, 0xFF, 0xCF, + 0xFF, 0xFF, 0xF8, 0xFF, 0xFF, 0xFF, 0x0F, 0xFF, 0xFF, 0xC0, 0xFF, 0xFF, + 0xFF, 0x0F, 0xFF, 0xFF, 0xF8, 0xFF, 0xFF, 0xFF, 0xCF, 0xF8, 0x0F, 0xFC, + 0xFF, 0x80, 0x3F, 0xCF, 0xF8, 0x03, 0xFE, 0xFF, 0x80, 0x1F, 0xEF, 0xF8, + 0x01, 0xFE, 0xFF, 0x80, 0x1F, 0xEF, 0xF8, 0x01, 0xFE, 0xFF, 0x80, 0x1F, + 0xEF, 0xF8, 0x01, 0xFE, 0xFF, 0x80, 0x1F, 0xFF, 0xF8, 0x01, 0xFF, 0xFF, + 0x80, 0x1F, 0xFF, 0xF8, 0x01, 0xFF, 0xFF, 0x80, 0x1F, 0xFF, 0xF8, 0x01, + 0xFF, 0xFF, 0x80, 0x1F, 0xFF, 0xF8, 0x01, 0xFF, 0xFF, 0x80, 0x1F, 0xFF, + 0xF8, 0x01, 0xFF, 0xFF, 0x80, 0x1F, 0xFF, 0xF8, 0x01, 0xFF, 0xFF, 0x80, + 0x1F, 0xFF, 0xF8, 0x01, 0xFF, 0xFF, 0x80, 0x1F, 0xFF, 0xF8, 0x01, 0xFF, + 0xFF, 0x80, 0x1F, 0xFF, 0xF8, 0x01, 0xFF, 0xFF, 0x80, 0x1F, 0xFF, 0xF8, + 0x01, 0xFF, 0xFF, 0x80, 0x1F, 0xFF, 0xF8, 0x01, 0xFF, 0xFF, 0x80, 0x1F, + 0xF0, 0x00, 0xFF, 0xC0, 0x00, 0x7F, 0xFF, 0x00, 0x3F, 0xFF, 0xF0, 0x0F, + 0xFF, 0xFF, 0x03, 0xFF, 0xFF, 0xF0, 0x7F, 0xFF, 0xFE, 0x1F, 0xFF, 0xFF, + 0xE3, 0xFF, 0xDF, 0xFC, 0x7F, 0xC0, 0xFF, 0x8F, 0xF0, 0x0F, 0xF3, 0xFE, + 0x01, 0xFF, 0x7F, 0xC0, 0x3F, 0xEF, 0xF8, 0x03, 0xFD, 0xFE, 0x00, 0x7F, + 0xBF, 0xC0, 0x0F, 0xF7, 0xF8, 0x01, 0xFE, 0xFF, 0x00, 0x3F, 0xDF, 0xF0, + 0x07, 0xFB, 0xFE, 0x00, 0xFF, 0x7F, 0xC0, 0x1F, 0xEF, 0xF8, 0x03, 0xFC, + 0xFF, 0x80, 0x7F, 0x9F, 0xF8, 0x0F, 0xF3, 0xFF, 0x80, 0x00, 0x3F, 0xF0, + 0x00, 0x07, 0xFF, 0x00, 0x00, 0x7F, 0xF0, 0x00, 0x0F, 0xFF, 0x00, 0x00, + 0xFF, 0xF0, 0x00, 0x0F, 0xFF, 0x00, 0x00, 0xFF, 0xF0, 0x00, 0x1F, 0xFF, + 0x00, 0x01, 0xFF, 0xF0, 0x00, 0x1F, 0xFF, 0x00, 0x01, 0xFF, 0xF0, 0x00, + 0x1F, 0xFE, 0x00, 0x01, 0xFF, 0xE0, 0x00, 0x1F, 0xFE, 0x00, 0x01, 0xFF, + 0xC0, 0x00, 0x1F, 0xFC, 0x00, 0x01, 0xFF, 0x80, 0x00, 0x1F, 0xFB, 0xFE, + 0x03, 0xFF, 0x7F, 0xC0, 0x3F, 0xEF, 0xF8, 0x07, 0xFD, 0xFF, 0x00, 0x7F, + 0xFF, 0xE0, 0x0F, 0xFF, 0xFC, 0x01, 0xFF, 0xFF, 0x80, 0x3F, 0xFF, 0xF0, + 0x07, 0xFF, 0xFE, 0x00, 0x7F, 0xFF, 0xC0, 0x0F, 0xFF, 0xF8, 0x03, 0xFF, + 0xFF, 0x00, 0x7F, 0xFF, 0xE0, 0x0F, 0xFB, 0xFC, 0x01, 0xFF, 0x7F, 0x80, + 0x3F, 0xEF, 0xF0, 0x07, 0xFD, 0xFF, 0x00, 0xFF, 0x3F, 0xE0, 0x3F, 0xE3, + 0xFE, 0x0F, 0xFC, 0x7F, 0xFF, 0xFF, 0x8F, 0xFF, 0xFF, 0xE0, 0xFF, 0xFF, + 0xFC, 0x0F, 0xFF, 0xFF, 0x01, 0xFF, 0xFF, 0xC0, 0x0F, 0xFF, 0xF0, 0x00, + 0xFF, 0xF8, 0x00, 0x01, 0xF8, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0x80, 0xFF, 0x80, 0x01, 0xFF, 0x00, 0x03, 0xFE, 0x00, 0x07, + 0xFC, 0x00, 0x0F, 0xF8, 0x00, 0x1F, 0xF0, 0x00, 0x3F, 0xE0, 0x00, 0x7F, + 0xC0, 0x00, 0xFF, 0x80, 0x01, 0xFF, 0x00, 0x03, 0xFE, 0x00, 0x07, 0xFC, + 0x00, 0x0F, 0xF8, 0x00, 0x1F, 0xF0, 0x00, 0x3F, 0xE0, 0x00, 0x7F, 0xC0, + 0x00, 0xFF, 0x80, 0x01, 0xFF, 0x00, 0x03, 0xFE, 0x00, 0x07, 0xFC, 0x00, + 0x0F, 0xF8, 0x00, 0x1F, 0xF0, 0x00, 0x3F, 0xE0, 0x00, 0x7F, 0xC0, 0x00, + 0xFF, 0x80, 0x01, 0xFF, 0x00, 0x03, 0xFE, 0x00, 0x07, 0xFC, 0x00, 0x0F, + 0xF8, 0x00, 0x1F, 0xF0, 0x00, 0x3F, 0xE0, 0x00, 0x7F, 0xC0, 0x00, 0xFF, + 0x80, 0x01, 0xFF, 0x00, 0x03, 0xFE, 0x00, 0x07, 0xFC, 0x00, 0x0F, 0xF8, + 0x00, 0x1F, 0xF0, 0x00, 0x3F, 0xE0, 0x00, 0x7F, 0xC0, 0x00, 0xFF, 0x80, + 0x01, 0xFF, 0x00, 0x03, 0xFE, 0x00, 0x07, 0xFC, 0x00, 0x0F, 0xF8, 0x00, + 0x1F, 0xF0, 0x00, 0x3F, 0xE0, 0x00, 0x7F, 0xC0, 0x00, 0xFF, 0x80, 0x01, + 0xFF, 0x00, 0x03, 0xFE, 0x00, 0x07, 0xFC, 0x00, 0x0F, 0xF8, 0x00, 0x1F, + 0xF0, 0x00, 0x3F, 0xE0, 0x00, 0x7F, 0xC0, 0x00, 0xFF, 0x80, 0x01, 0xFF, + 0x00, 0x03, 0xFE, 0x00, 0x07, 0xFC, 0x00, 0xFF, 0x80, 0x1F, 0xFF, 0xF8, + 0x01, 0xFF, 0xFF, 0x80, 0x1F, 0xFF, 0xF8, 0x01, 0xFF, 0xFF, 0x80, 0x1F, + 0xFF, 0xF8, 0x01, 0xFF, 0xFF, 0x80, 0x1F, 0xFF, 0xF8, 0x01, 0xFF, 0xFF, + 0x80, 0x1F, 0xFF, 0xF8, 0x01, 0xFF, 0xFF, 0x80, 0x1F, 0xFF, 0xF8, 0x01, + 0xFF, 0xFF, 0x80, 0x1F, 0xFF, 0xF8, 0x01, 0xFF, 0xFF, 0x80, 0x1F, 0xFF, + 0xF8, 0x01, 0xFF, 0xFF, 0x80, 0x1F, 0xFF, 0xF8, 0x01, 0xFF, 0xFF, 0x80, + 0x1F, 0xFF, 0xF8, 0x01, 0xFF, 0xFF, 0x80, 0x1F, 0xFF, 0xF8, 0x01, 0xFF, + 0xFF, 0x80, 0x1F, 0xFF, 0xF8, 0x01, 0xFF, 0xFF, 0x80, 0x1F, 0xFF, 0xF8, + 0x01, 0xFF, 0xFF, 0x80, 0x1F, 0xFF, 0xF8, 0x01, 0xFF, 0xFF, 0x80, 0x1F, + 0xFF, 0xF8, 0x01, 0xFF, 0xFF, 0x80, 0x1F, 0xFF, 0xF8, 0x01, 0xFF, 0xFF, + 0x80, 0x1F, 0xFF, 0xF8, 0x01, 0xFF, 0xFF, 0x80, 0x1F, 0xFF, 0xF8, 0x01, + 0xFF, 0xFF, 0x80, 0x1F, 0xFF, 0xF8, 0x01, 0xFF, 0xFF, 0x80, 0x1F, 0xFF, + 0xF8, 0x01, 0xFF, 0xFF, 0x80, 0x1F, 0xFF, 0xF8, 0x01, 0xFF, 0xFF, 0x80, + 0x1F, 0xFF, 0xF8, 0x01, 0xFF, 0xFF, 0x80, 0x1F, 0xFF, 0xF8, 0x01, 0xFF, + 0xFF, 0x80, 0x1F, 0xFF, 0xF8, 0x01, 0xFF, 0xFF, 0x80, 0x1F, 0xFF, 0xF8, + 0x01, 0xFF, 0xFF, 0x80, 0x1F, 0xFF, 0xF8, 0x01, 0xFF, 0xFF, 0x80, 0x1F, + 0xFF, 0xF8, 0x01, 0xFE, 0xFF, 0x80, 0x1F, 0xEF, 0xF8, 0x01, 0xFE, 0xFF, + 0x80, 0x3F, 0xEF, 0xF8, 0x03, 0xFE, 0x7F, 0xC0, 0x3F, 0xE7, 0xFE, 0x07, + 0xFC, 0x7F, 0xFF, 0xFF, 0xC3, 0xFF, 0xFF, 0xFC, 0x3F, 0xFF, 0xFF, 0x81, + 0xFF, 0xFF, 0xF0, 0x0F, 0xFF, 0xFF, 0x00, 0x7F, 0xFF, 0xC0, 0x01, 0xFF, + 0xF8, 0x00, 0x01, 0xFC, 0x00, 0xFF, 0x00, 0x01, 0xFF, 0xFE, 0x00, 0x07, + 0xFF, 0xFC, 0x00, 0x0F, 0xFF, 0xFC, 0x00, 0x1F, 0xEF, 0xF8, 0x00, 0x3F, + 0xDF, 0xF0, 0x00, 0x7F, 0x9F, 0xE0, 0x00, 0xFF, 0x3F, 0xC0, 0x01, 0xFE, + 0x7F, 0x80, 0x03, 0xFC, 0xFF, 0x00, 0x0F, 0xF9, 0xFF, 0x00, 0x1F, 0xE3, + 0xFE, 0x00, 0x3F, 0xC3, 0xFC, 0x00, 0x7F, 0x87, 0xF8, 0x00, 0xFF, 0x0F, + 0xF0, 0x01, 0xFE, 0x1F, 0xE0, 0x03, 0xFC, 0x3F, 0xE0, 0x0F, 0xF8, 0x7F, + 0xC0, 0x1F, 0xE0, 0x7F, 0x80, 0x3F, 0xC0, 0xFF, 0x00, 0x7F, 0x81, 0xFE, + 0x00, 0xFF, 0x03, 0xFC, 0x01, 0xFE, 0x07, 0xF8, 0x03, 0xFC, 0x0F, 0xF8, + 0x07, 0xF0, 0x0F, 0xF0, 0x1F, 0xE0, 0x1F, 0xE0, 0x3F, 0xC0, 0x3F, 0xC0, + 0x7F, 0x80, 0x7F, 0x80, 0xFF, 0x00, 0xFF, 0x01, 0xFE, 0x01, 0xFF, 0x03, + 0xFC, 0x03, 0xFE, 0x07, 0xF0, 0x03, 0xFC, 0x0F, 0xE0, 0x07, 0xF8, 0x3F, + 0xC0, 0x0F, 0xF0, 0x7F, 0x80, 0x1F, 0xE0, 0xFF, 0x00, 0x3F, 0xC1, 0xFE, + 0x00, 0x7F, 0xC3, 0xFC, 0x00, 0x7F, 0x87, 0xF0, 0x00, 0xFF, 0x0F, 0xE0, + 0x01, 0xFE, 0x1F, 0xC0, 0x03, 0xFC, 0x7F, 0x80, 0x07, 0xF8, 0xFF, 0x00, + 0x0F, 0xF1, 0xFE, 0x00, 0x0F, 0xF3, 0xFC, 0x00, 0x1F, 0xE7, 0xF0, 0x00, + 0x3F, 0xCF, 0xE0, 0x00, 0x7F, 0x9F, 0xC0, 0x00, 0xFF, 0x3F, 0x80, 0x01, + 0xFE, 0xFF, 0x00, 0x01, 0xFD, 0xFE, 0x00, 0x03, 0xFF, 0xFC, 0x00, 0x07, + 0xFF, 0xF0, 0x00, 0x0F, 0xFF, 0xE0, 0x00, 0x1F, 0xFF, 0xC0, 0x00, 0x3F, + 0xFF, 0x80, 0x00, 0x3F, 0xFF, 0x00, 0x00, 0x7F, 0xFE, 0x00, 0x00, 0xFF, + 0xF8, 0x00, 0x01, 0xFF, 0xF0, 0x00, 0x03, 0xFF, 0xE0, 0x00, 0x07, 0xFF, + 0xC0, 0x00, 0x07, 0xFF, 0x80, 0x00, 0x0F, 0xFF, 0x00, 0x00, 0x1F, 0xFE, + 0x00, 0x00, 0x3F, 0xF8, 0x00, 0x00, 0x7F, 0xF0, 0x00, 0x00, 0xFF, 0xE0, + 0x00, 0xFF, 0x00, 0x0F, 0xF0, 0x01, 0xFF, 0xFF, 0x00, 0x0F, 0xF0, 0x01, + 0xFE, 0xFF, 0x00, 0x0F, 0xF0, 0x01, 0xFE, 0xFF, 0x00, 0x0F, 0xF0, 0x01, + 0xFE, 0x7F, 0x80, 0x0F, 0xF0, 0x01, 0xFE, 0x7F, 0x80, 0x0F, 0xF8, 0x01, + 0xFE, 0x7F, 0x80, 0x0F, 0xF8, 0x01, 0xFE, 0x7F, 0x80, 0x1F, 0xF8, 0x01, + 0xFE, 0x7F, 0x80, 0x1F, 0xF8, 0x01, 0xFE, 0x7F, 0x80, 0x1F, 0xF8, 0x01, + 0xFE, 0x7F, 0x80, 0x1F, 0xF8, 0x01, 0xFC, 0x7F, 0x80, 0x1F, 0xF8, 0x03, + 0xFC, 0x3F, 0x80, 0x1F, 0xFC, 0x03, 0xFC, 0x3F, 0xC0, 0x1F, 0xFC, 0x03, + 0xFC, 0x3F, 0xC0, 0x3F, 0xFC, 0x03, 0xFC, 0x3F, 0xC0, 0x3F, 0xFC, 0x03, + 0xFC, 0x3F, 0xC0, 0x3F, 0xFC, 0x03, 0xFC, 0x3F, 0xC0, 0x3F, 0xFC, 0x03, + 0xFC, 0x3F, 0xC0, 0x3F, 0xFC, 0x03, 0xF8, 0x3F, 0xC0, 0x3F, 0xFE, 0x03, + 0xF8, 0x1F, 0xC0, 0x3F, 0xFE, 0x03, 0xF8, 0x1F, 0xC0, 0x7F, 0x7E, 0x03, + 0xF8, 0x1F, 0xC0, 0x7F, 0x7E, 0x07, 0xF8, 0x1F, 0xE0, 0x7F, 0x7E, 0x07, + 0xF8, 0x1F, 0xE0, 0x7F, 0x7E, 0x07, 0xF8, 0x1F, 0xE0, 0x7E, 0x7E, 0x07, + 0xF8, 0x1F, 0xE0, 0x7E, 0x7F, 0x07, 0xF8, 0x0F, 0xE0, 0x7E, 0x7F, 0x07, + 0xF0, 0x0F, 0xE0, 0xFE, 0x3F, 0x07, 0xF0, 0x0F, 0xE0, 0xFE, 0x3F, 0x07, + 0xF0, 0x0F, 0xE0, 0xFE, 0x3F, 0x07, 0xF0, 0x0F, 0xE0, 0xFE, 0x3F, 0x07, + 0xF0, 0x0F, 0xF0, 0xFC, 0x3F, 0x0F, 0xF0, 0x0F, 0xF0, 0xFC, 0x3F, 0x8F, + 0xF0, 0x0F, 0xF0, 0xFC, 0x3F, 0x8F, 0xF0, 0x07, 0xF1, 0xFC, 0x1F, 0x8F, + 0xE0, 0x07, 0xF1, 0xFC, 0x1F, 0x8F, 0xE0, 0x07, 0xF1, 0xFC, 0x1F, 0x8F, + 0xE0, 0x07, 0xF1, 0xF8, 0x1F, 0x8F, 0xE0, 0x07, 0xF1, 0xF8, 0x1F, 0x8F, + 0xE0, 0x07, 0xF1, 0xF8, 0x1F, 0xCF, 0xE0, 0x07, 0xF9, 0xF8, 0x1F, 0xCF, + 0xE0, 0x07, 0xFB, 0xF8, 0x0F, 0xCF, 0xE0, 0x03, 0xFB, 0xF8, 0x0F, 0xDF, + 0xE0, 0x03, 0xFB, 0xF8, 0x0F, 0xDF, 0xC0, 0x03, 0xFB, 0xF0, 0x0F, 0xDF, + 0xC0, 0x03, 0xFB, 0xF0, 0x0F, 0xDF, 0xC0, 0x03, 0xFB, 0xF0, 0x0F, 0xFF, + 0xC0, 0x03, 0xFB, 0xF0, 0x0F, 0xFF, 0xC0, 0x03, 0xFF, 0xF0, 0x07, 0xFF, + 0xC0, 0x03, 0xFF, 0xF0, 0x07, 0xFF, 0xC0, 0x01, 0xFF, 0xF0, 0x07, 0xFF, + 0xC0, 0x01, 0xFF, 0xE0, 0x07, 0xFF, 0xC0, 0x01, 0xFF, 0xE0, 0x07, 0xFF, + 0x80, 0x01, 0xFF, 0xE0, 0x07, 0xFF, 0x80, 0x01, 0xFF, 0xE0, 0x07, 0xFF, + 0x80, 0x01, 0xFF, 0xE0, 0x03, 0xFF, 0x80, 0x01, 0xFF, 0xE0, 0x03, 0xFF, + 0x80, 0x01, 0xFF, 0xE0, 0x03, 0xFF, 0x80, 0x00, 0xFF, 0xC0, 0x03, 0xFF, + 0x80, 0x00, 0xFF, 0xC0, 0x03, 0xFF, 0x80, 0x00, 0xFF, 0xC0, 0x03, 0xFF, + 0x00, 0x00, 0xFF, 0xC0, 0x03, 0xFF, 0x00, 0x00, 0xFF, 0xC0, 0x03, 0xFF, + 0x00, 0x00, 0xFF, 0xC0, 0x01, 0xFF, 0x00, 0x00, 0xFF, 0xC0, 0x01, 0xFF, + 0x00, 0x00, 0xFF, 0x80, 0x01, 0xFF, 0x00, 0xFF, 0x00, 0x1F, 0xFF, 0xF0, + 0x01, 0xFE, 0x7F, 0x00, 0x1F, 0xE7, 0xF8, 0x01, 0xFE, 0x7F, 0x80, 0x3F, + 0xE3, 0xF8, 0x03, 0xFC, 0x3F, 0xC0, 0x3F, 0xC3, 0xFC, 0x03, 0xFC, 0x1F, + 0xC0, 0x7F, 0x81, 0xFE, 0x07, 0xF8, 0x1F, 0xE0, 0x7F, 0x81, 0xFE, 0x07, + 0xF8, 0x0F, 0xE0, 0xFF, 0x00, 0xFF, 0x0F, 0xF0, 0x0F, 0xF0, 0xFF, 0x00, + 0x7F, 0x0F, 0xE0, 0x07, 0xF9, 0xFE, 0x00, 0x7F, 0x9F, 0xE0, 0x03, 0xF9, + 0xFE, 0x00, 0x3F, 0xDF, 0xC0, 0x03, 0xFF, 0xFC, 0x00, 0x1F, 0xFF, 0xC0, + 0x01, 0xFF, 0xF8, 0x00, 0x1F, 0xFF, 0x80, 0x00, 0xFF, 0xF8, 0x00, 0x0F, + 0xFF, 0x80, 0x00, 0xFF, 0xF0, 0x00, 0x0F, 0xFF, 0x00, 0x00, 0x7F, 0xF0, + 0x00, 0x07, 0xFF, 0x00, 0x00, 0x7F, 0xE0, 0x00, 0x07, 0xFE, 0x00, 0x00, + 0x7F, 0xE0, 0x00, 0x07, 0xFC, 0x00, 0x00, 0x7F, 0xC0, 0x00, 0x0F, 0xFE, + 0x00, 0x00, 0xFF, 0xE0, 0x00, 0x0F, 0xFE, 0x00, 0x00, 0xFF, 0xF0, 0x00, + 0x1F, 0xFF, 0x00, 0x01, 0xFF, 0xF0, 0x00, 0x1F, 0xFF, 0x00, 0x03, 0xFF, + 0xF8, 0x00, 0x3F, 0xFF, 0x80, 0x03, 0xFF, 0xF8, 0x00, 0x3F, 0xFF, 0xC0, + 0x07, 0xFB, 0xFC, 0x00, 0x7F, 0x9F, 0xC0, 0x07, 0xF9, 0xFE, 0x00, 0xFF, + 0x9F, 0xE0, 0x0F, 0xF0, 0xFE, 0x00, 0xFF, 0x0F, 0xF0, 0x0F, 0xF0, 0xFF, + 0x01, 0xFF, 0x07, 0xF0, 0x1F, 0xE0, 0x7F, 0x81, 0xFE, 0x07, 0xF8, 0x1F, + 0xE0, 0x7F, 0x83, 0xFE, 0x03, 0xF8, 0x3F, 0xC0, 0x3F, 0xC3, 0xFC, 0x03, + 0xFC, 0x7F, 0xC0, 0x1F, 0xC7, 0xF8, 0x01, 0xFE, 0x7F, 0x80, 0x1F, 0xE7, + 0xF8, 0x00, 0xFE, 0xFF, 0x80, 0x0F, 0xFF, 0xF0, 0x00, 0xFF, 0xFF, 0x00, + 0x07, 0xF0, 0xFF, 0x00, 0x03, 0xFF, 0xFF, 0x00, 0x07, 0xFB, 0xFE, 0x00, + 0x1F, 0xF3, 0xFC, 0x00, 0x3F, 0xE7, 0xFC, 0x00, 0x7F, 0xCF, 0xF8, 0x00, + 0xFF, 0x0F, 0xF0, 0x03, 0xFE, 0x1F, 0xE0, 0x07, 0xFC, 0x3F, 0xE0, 0x0F, + 0xF0, 0x7F, 0xC0, 0x1F, 0xE0, 0x7F, 0x80, 0x3F, 0xC0, 0xFF, 0x80, 0xFF, + 0x81, 0xFF, 0x01, 0xFE, 0x01, 0xFE, 0x03, 0xFC, 0x03, 0xFC, 0x07, 0xF8, + 0x07, 0xFC, 0x1F, 0xF0, 0x0F, 0xF8, 0x3F, 0xC0, 0x0F, 0xF0, 0x7F, 0x80, + 0x1F, 0xE0, 0xFF, 0x00, 0x3F, 0xE3, 0xFC, 0x00, 0x3F, 0xC7, 0xF8, 0x00, + 0x7F, 0x8F, 0xF0, 0x00, 0xFF, 0x9F, 0xE0, 0x00, 0xFF, 0x7F, 0x80, 0x01, + 0xFE, 0xFF, 0x00, 0x03, 0xFD, 0xFE, 0x00, 0x07, 0xFF, 0xFC, 0x00, 0x07, + 0xFF, 0xF0, 0x00, 0x0F, 0xFF, 0xE0, 0x00, 0x1F, 0xFF, 0xC0, 0x00, 0x1F, + 0xFF, 0x00, 0x00, 0x3F, 0xFE, 0x00, 0x00, 0x7F, 0xFC, 0x00, 0x00, 0xFF, + 0xF8, 0x00, 0x00, 0xFF, 0xE0, 0x00, 0x01, 0xFF, 0xC0, 0x00, 0x03, 0xFF, + 0x80, 0x00, 0x03, 0xFF, 0x00, 0x00, 0x07, 0xFC, 0x00, 0x00, 0x0F, 0xF8, + 0x00, 0x00, 0x1F, 0xF0, 0x00, 0x00, 0x3F, 0xE0, 0x00, 0x00, 0x7F, 0xC0, + 0x00, 0x00, 0xFF, 0x80, 0x00, 0x01, 0xFF, 0x00, 0x00, 0x03, 0xFE, 0x00, + 0x00, 0x07, 0xFC, 0x00, 0x00, 0x0F, 0xF8, 0x00, 0x00, 0x1F, 0xF0, 0x00, + 0x00, 0x3F, 0xE0, 0x00, 0x00, 0x7F, 0xC0, 0x00, 0x00, 0xFF, 0x80, 0x00, + 0x01, 0xFF, 0x00, 0x00, 0x03, 0xFE, 0x00, 0x00, 0x07, 0xFC, 0x00, 0x00, + 0x0F, 0xF8, 0x00, 0x00, 0x1F, 0xF0, 0x00, 0x00, 0x3F, 0xE0, 0x00, 0x00, + 0x7F, 0xC0, 0x00, 0x00, 0xFF, 0x80, 0x00, 0x01, 0xFF, 0x00, 0x00, 0x03, + 0xFE, 0x00, 0x00, 0x07, 0xFC, 0x00, 0x00, 0x0F, 0xF8, 0x00, 0x00, 0x1F, + 0xF0, 0x00, 0x00, 0x3F, 0xE0, 0x00, 0x00, 0x7F, 0xC0, 0x00, 0x7F, 0xFF, + 0xFE, 0xFF, 0xFF, 0xFD, 0xFF, 0xFF, 0xFB, 0xFF, 0xFF, 0xF7, 0xFF, 0xFF, + 0xEF, 0xFF, 0xFF, 0xDF, 0xFF, 0xFF, 0x80, 0x03, 0xFE, 0x00, 0x07, 0xFC, + 0x00, 0x0F, 0xF8, 0x00, 0x1F, 0xF0, 0x00, 0x7F, 0xC0, 0x00, 0xFF, 0x80, + 0x01, 0xFF, 0x00, 0x07, 0xFE, 0x00, 0x0F, 0xF8, 0x00, 0x1F, 0xF0, 0x00, + 0x3F, 0xE0, 0x00, 0xFF, 0xC0, 0x01, 0xFF, 0x00, 0x03, 0xFE, 0x00, 0x07, + 0xFC, 0x00, 0x1F, 0xF8, 0x00, 0x3F, 0xE0, 0x00, 0x7F, 0xC0, 0x00, 0xFF, + 0x80, 0x03, 0xFE, 0x00, 0x07, 0xFC, 0x00, 0x0F, 0xF8, 0x00, 0x3F, 0xF0, + 0x00, 0x7F, 0xC0, 0x00, 0xFF, 0x80, 0x01, 0xFF, 0x00, 0x07, 0xFE, 0x00, + 0x0F, 0xF8, 0x00, 0x1F, 0xF0, 0x00, 0x3F, 0xE0, 0x00, 0xFF, 0xC0, 0x01, + 0xFF, 0x00, 0x03, 0xFE, 0x00, 0x07, 0xFC, 0x00, 0x1F, 0xF8, 0x00, 0x3F, + 0xE0, 0x00, 0x7F, 0xC0, 0x01, 0xFF, 0x80, 0x03, 0xFE, 0x00, 0x07, 0xFC, + 0x00, 0x0F, 0xF8, 0x00, 0x3F, 0xF0, 0x00, 0x7F, 0xC0, 0x00, 0xFF, 0x80, + 0x01, 0xFF, 0x00, 0x07, 0xFE, 0x00, 0x0F, 0xF8, 0x00, 0x1F, 0xF0, 0x00, + 0x3F, 0xE0, 0x00, 0xFF, 0xC0, 0x01, 0xFF, 0x00, 0x03, 0xFE, 0x00, 0x07, + 0xFF, 0xFF, 0xEF, 0xFF, 0xFF, 0xDF, 0xFF, 0xFF, 0xBF, 0xFF, 0xFF, 0x7F, + 0xFF, 0xFE, 0xFF, 0xFF, 0xFD, 0xFF, 0xFF, 0xFB, 0xFF, 0xFF, 0xF0, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0x80, 0x7F, 0xC0, 0x3F, 0xE0, 0x1F, 0xF0, + 0x0F, 0xF8, 0x07, 0xFC, 0x03, 0xFE, 0x01, 0xFF, 0x00, 0xFF, 0x80, 0x7F, + 0xC0, 0x3F, 0xE0, 0x1F, 0xF0, 0x0F, 0xF8, 0x07, 0xFC, 0x03, 0xFE, 0x01, + 0xFF, 0x00, 0xFF, 0x80, 0x7F, 0xC0, 0x3F, 0xE0, 0x1F, 0xF0, 0x0F, 0xF8, + 0x07, 0xFC, 0x03, 0xFE, 0x01, 0xFF, 0x00, 0xFF, 0x80, 0x7F, 0xC0, 0x3F, + 0xE0, 0x1F, 0xF0, 0x0F, 0xF8, 0x07, 0xFC, 0x03, 0xFE, 0x01, 0xFF, 0x00, + 0xFF, 0x80, 0x7F, 0xC0, 0x3F, 0xE0, 0x1F, 0xF0, 0x0F, 0xF8, 0x07, 0xFC, + 0x03, 0xFE, 0x01, 0xFF, 0x00, 0xFF, 0x80, 0x7F, 0xC0, 0x3F, 0xE0, 0x1F, + 0xF0, 0x0F, 0xF8, 0x07, 0xFC, 0x03, 0xFE, 0x01, 0xFF, 0x00, 0xFF, 0x80, + 0x7F, 0xC0, 0x3F, 0xE0, 0x1F, 0xF0, 0x0F, 0xF8, 0x07, 0xFC, 0x03, 0xFE, + 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFC, 0xFF, 0x00, 0x00, 0x7F, 0x00, 0x00, 0x7F, 0x80, + 0x00, 0x7F, 0x80, 0x00, 0x7F, 0x80, 0x00, 0x3F, 0x80, 0x00, 0x3F, 0xC0, + 0x00, 0x3F, 0xC0, 0x00, 0x3F, 0xC0, 0x00, 0x3F, 0xC0, 0x00, 0x1F, 0xE0, + 0x00, 0x1F, 0xE0, 0x00, 0x1F, 0xE0, 0x00, 0x1F, 0xE0, 0x00, 0x0F, 0xE0, + 0x00, 0x0F, 0xF0, 0x00, 0x0F, 0xF0, 0x00, 0x0F, 0xF0, 0x00, 0x07, 0xF0, + 0x00, 0x07, 0xF8, 0x00, 0x07, 0xF8, 0x00, 0x07, 0xF8, 0x00, 0x07, 0xF8, + 0x00, 0x03, 0xFC, 0x00, 0x03, 0xFC, 0x00, 0x03, 0xFC, 0x00, 0x03, 0xFC, + 0x00, 0x01, 0xFC, 0x00, 0x01, 0xFE, 0x00, 0x01, 0xFE, 0x00, 0x01, 0xFE, + 0x00, 0x00, 0xFE, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, + 0x00, 0x00, 0xFF, 0x00, 0x00, 0x7F, 0x80, 0x00, 0x7F, 0x80, 0x00, 0x7F, + 0x80, 0x00, 0x7F, 0x80, 0x00, 0x3F, 0x80, 0x00, 0x3F, 0xC0, 0x00, 0x3F, + 0xC0, 0x00, 0x3F, 0xC0, 0x00, 0x1F, 0xC0, 0x00, 0x1F, 0xE0, 0x00, 0x1F, + 0xE0, 0x00, 0x1F, 0xE0, 0x00, 0x0F, 0xE0, 0x00, 0x0F, 0xF0, 0x00, 0x0F, + 0xF0, 0x00, 0x0F, 0xF0, 0x00, 0x0F, 0xF0, 0x00, 0x07, 0xF8, 0x00, 0x07, + 0xF8, 0x00, 0x07, 0xF8, 0x00, 0x07, 0xF8, 0x00, 0x03, 0xF8, 0x00, 0x03, + 0xFC, 0x00, 0x03, 0xFC, 0x00, 0x03, 0xFC, 0x00, 0x01, 0xFC, 0x00, 0x01, + 0xFE, 0x00, 0x01, 0xFE, 0x00, 0x01, 0xFE, 0x00, 0x00, 0xFE, 0x00, 0x00, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, + 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, + 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, + 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, + 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, + 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, + 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, + 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, + 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, + 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x7F, 0xF0, + 0x00, 0x03, 0xFF, 0x80, 0x00, 0x3F, 0xFE, 0x00, 0x01, 0xFF, 0xF0, 0x00, + 0x0F, 0xFF, 0x80, 0x00, 0xFF, 0xFC, 0x00, 0x07, 0xFF, 0xF0, 0x00, 0x3F, + 0xBF, 0x80, 0x01, 0xFD, 0xFC, 0x00, 0x1F, 0xEF, 0xE0, 0x00, 0xFF, 0x7F, + 0x80, 0x07, 0xF1, 0xFC, 0x00, 0x3F, 0x8F, 0xE0, 0x03, 0xFC, 0x7F, 0x80, + 0x1F, 0xE3, 0xFC, 0x00, 0xFF, 0x1F, 0xE0, 0x07, 0xF0, 0x7F, 0x00, 0x7F, + 0x83, 0xFC, 0x03, 0xFC, 0x1F, 0xE0, 0x1F, 0xE0, 0xFF, 0x00, 0xFF, 0x07, + 0xF8, 0x0F, 0xF0, 0x1F, 0xE0, 0x7F, 0x80, 0xFF, 0x03, 0xFC, 0x07, 0xF8, + 0x1F, 0xE0, 0x3F, 0xC1, 0xFE, 0x00, 0xFF, 0x0F, 0xF0, 0x07, 0xF8, 0x7F, + 0x80, 0x3F, 0xC7, 0xFC, 0x01, 0xFE, 0x3F, 0xE0, 0x0F, 0xF9, 0xFE, 0x00, + 0x3F, 0xCF, 0xF0, 0x01, 0xFE, 0xFF, 0x80, 0x0F, 0xF7, 0xFC, 0x00, 0x7F, + 0xFF, 0xE0, 0x03, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFE, 0xFF, 0x8F, 0xF8, 0x7F, 0x87, 0xFC, 0x3F, 0xC3, 0xFC, 0x1F, + 0xC0, 0xFE, 0x0F, 0xE0, 0x7E, 0x07, 0xE0, 0x3F, 0x03, 0xF0, 0x1F, 0x01, + 0xF0, 0x00, 0x7F, 0xE0, 0x00, 0x3F, 0xFF, 0x00, 0x1F, 0xFF, 0xF8, 0x07, + 0xFF, 0xFF, 0x81, 0xFF, 0xFF, 0xF0, 0x3F, 0xFF, 0xFF, 0x0F, 0xFF, 0xFF, + 0xE1, 0xFF, 0x87, 0xFE, 0x3F, 0xE0, 0x7F, 0xCF, 0xF8, 0x07, 0xF9, 0xFF, + 0x00, 0xFF, 0xBF, 0xE0, 0x1F, 0xF7, 0xFC, 0x03, 0xFE, 0xFF, 0x80, 0x7F, + 0xDF, 0xF0, 0x0F, 0xFB, 0xFE, 0x01, 0xFF, 0x7F, 0xC0, 0x3F, 0xEF, 0xF8, + 0x07, 0xFD, 0xFF, 0x00, 0xFF, 0x80, 0x00, 0x1F, 0xF0, 0x00, 0x03, 0xFE, + 0x00, 0x00, 0xFF, 0xC0, 0x00, 0x7F, 0xF8, 0x00, 0x7F, 0xFF, 0x00, 0x3F, + 0xFF, 0xE0, 0x1F, 0xFF, 0xFC, 0x0F, 0xFF, 0xFF, 0x83, 0xFF, 0x9F, 0xF0, + 0xFF, 0xC3, 0xFE, 0x3F, 0xE0, 0x7F, 0xCF, 0xF8, 0x0F, 0xFB, 0xFE, 0x01, + 0xFF, 0x7F, 0xC0, 0x3F, 0xEF, 0xF0, 0x07, 0xFF, 0xFE, 0x00, 0xFF, 0xFF, + 0xC0, 0x1F, 0xFF, 0xF8, 0x03, 0xFF, 0xFF, 0x00, 0x7F, 0xFF, 0xE0, 0x0F, + 0xFF, 0xFC, 0x01, 0xFF, 0xFF, 0x80, 0x3F, 0xFF, 0xF0, 0x07, 0xFF, 0xFE, + 0x00, 0xFF, 0xFF, 0xC0, 0x1F, 0xFF, 0xF8, 0x03, 0xFF, 0xFF, 0x00, 0x7F, + 0xFF, 0xE0, 0x0F, 0xFF, 0xFC, 0x01, 0xFF, 0x7F, 0xC0, 0x3F, 0xEF, 0xF8, + 0x0F, 0xFD, 0xFF, 0x03, 0xFF, 0xBF, 0xFB, 0xFF, 0xF3, 0xFF, 0xFF, 0xFE, + 0x7F, 0xFF, 0xFF, 0xC7, 0xFF, 0xEF, 0xF8, 0xFF, 0xFD, 0xFF, 0x0F, 0xFF, + 0x3F, 0xE0, 0x7F, 0x87, 0xFC, 0x00, 0x80, 0x00, 0x00, 0xFF, 0x80, 0x00, + 0x1F, 0xF0, 0x00, 0x03, 0xFE, 0x00, 0x00, 0x7F, 0xC0, 0x00, 0x0F, 0xF8, + 0x00, 0x01, 0xFF, 0x00, 0x00, 0x3F, 0xE0, 0x00, 0x07, 0xFC, 0x00, 0x00, + 0xFF, 0x80, 0x00, 0x1F, 0xF0, 0x00, 0x03, 0xFE, 0x0F, 0xC0, 0x7F, 0xC7, + 0xFE, 0x0F, 0xF9, 0xFF, 0xF1, 0xFF, 0x7F, 0xFE, 0x3F, 0xFF, 0xFF, 0xE7, + 0xFF, 0xFF, 0xFC, 0xFF, 0xFF, 0xFF, 0xDF, 0xFF, 0x1F, 0xFB, 0xFF, 0x81, + 0xFF, 0x7F, 0xE0, 0x1F, 0xFF, 0xFC, 0x03, 0xFF, 0xFF, 0x80, 0x7F, 0xFF, + 0xF0, 0x0F, 0xFF, 0xFC, 0x01, 0xFF, 0xFF, 0x80, 0x3F, 0xFF, 0xF0, 0x07, + 0xFF, 0xFE, 0x00, 0xFF, 0xFF, 0xC0, 0x0F, 0xFF, 0xF8, 0x01, 0xFF, 0xFF, + 0x00, 0x3F, 0xFF, 0xE0, 0x07, 0xFF, 0xFC, 0x00, 0xFF, 0xFF, 0x80, 0x1F, + 0xFF, 0xF0, 0x03, 0xFF, 0xFE, 0x00, 0x7F, 0xFF, 0xC0, 0x0F, 0xFF, 0xF8, + 0x01, 0xFF, 0xFF, 0x00, 0x3F, 0xFF, 0xE0, 0x07, 0xFF, 0xFC, 0x00, 0xFF, + 0xFF, 0x80, 0x1F, 0xFF, 0xF0, 0x03, 0xFF, 0xFE, 0x00, 0x7F, 0xFF, 0xC0, + 0x0F, 0xFF, 0xF8, 0x01, 0xFF, 0xFF, 0x00, 0x3F, 0xFF, 0xE0, 0x07, 0xFF, + 0xFC, 0x00, 0xFF, 0xFF, 0x80, 0x1F, 0xFF, 0xF0, 0x03, 0xFF, 0xFE, 0x00, + 0xFF, 0xFF, 0xC0, 0x1F, 0xFF, 0xF8, 0x03, 0xFF, 0xFF, 0x00, 0x7F, 0xFF, + 0xE0, 0x0F, 0xFF, 0xFE, 0x01, 0xFF, 0xFF, 0xC0, 0x3F, 0xFF, 0xF8, 0x07, + 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xF0, 0x3F, 0xFF, 0xFE, 0x07, 0xFD, 0xFF, + 0xFF, 0xFF, 0xBF, 0xFF, 0xFF, 0xF7, 0xFF, 0xFF, 0xFC, 0xFF, 0xBF, 0xFF, + 0x9F, 0xF3, 0xFF, 0xE3, 0xFE, 0x3F, 0xF8, 0x7F, 0xC3, 0xFE, 0x00, 0x00, + 0x04, 0x00, 0x00, 0xFF, 0xC0, 0x00, 0xFF, 0xFC, 0x00, 0xFF, 0xFF, 0xC0, + 0x7F, 0xFF, 0xF0, 0x1F, 0xFF, 0xFE, 0x0F, 0xFF, 0xFF, 0xC7, 0xFF, 0xFF, + 0xF1, 0xFF, 0xCF, 0xFE, 0x7F, 0xC0, 0xFF, 0x9F, 0xE0, 0x1F, 0xEF, 0xF8, + 0x07, 0xFB, 0xFE, 0x01, 0xFE, 0xFF, 0x80, 0x7F, 0xFF, 0xE0, 0x1F, 0xFF, + 0xF0, 0x07, 0xFF, 0xFC, 0x01, 0xFF, 0xFF, 0x00, 0x7F, 0xFF, 0xC0, 0x1F, + 0xFF, 0xF0, 0x07, 0xFF, 0xFC, 0x01, 0xFF, 0xFF, 0x00, 0x7F, 0xFF, 0xC0, + 0x1F, 0xFF, 0xF0, 0x00, 0x03, 0xFC, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x3F, + 0xC0, 0x00, 0x0F, 0xF0, 0x00, 0x03, 0xFC, 0x00, 0x00, 0xFF, 0x00, 0x00, + 0x3F, 0xC0, 0x00, 0x0F, 0xF0, 0x00, 0x03, 0xFC, 0x00, 0x00, 0xFF, 0x00, + 0x00, 0x3F, 0xC0, 0x00, 0x0F, 0xF0, 0x00, 0x03, 0xFC, 0x00, 0x00, 0xFF, + 0x00, 0x7F, 0xFF, 0xC0, 0x1F, 0xFF, 0xF0, 0x07, 0xFF, 0xFC, 0x01, 0xFF, + 0xFF, 0x00, 0x7F, 0xFF, 0xC0, 0x1F, 0xFF, 0xF0, 0x07, 0xFF, 0xFC, 0x01, + 0xFF, 0xFF, 0x00, 0x7F, 0xFF, 0xE0, 0x1F, 0xFF, 0xF8, 0x07, 0xFB, 0xFE, + 0x01, 0xFE, 0xFF, 0x80, 0x7F, 0x9F, 0xE0, 0x3F, 0xE7, 0xFC, 0x1F, 0xF9, + 0xFF, 0xFF, 0xFC, 0x3F, 0xFF, 0xFF, 0x0F, 0xFF, 0xFF, 0x81, 0xFF, 0xFF, + 0xE0, 0x3F, 0xFF, 0xF0, 0x07, 0xFF, 0xF8, 0x00, 0x7F, 0xF8, 0x00, 0x01, + 0xE0, 0x00, 0x00, 0x00, 0x3F, 0xC0, 0x00, 0x0F, 0xF0, 0x00, 0x03, 0xFC, + 0x00, 0x00, 0xFF, 0x00, 0x00, 0x3F, 0xC0, 0x00, 0x0F, 0xF0, 0x00, 0x03, + 0xFC, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x3F, 0xC0, 0x00, 0x0F, 0xF0, 0x1F, + 0xC3, 0xFC, 0x1F, 0xF8, 0xFF, 0x0F, 0xFF, 0x3F, 0xC7, 0xFF, 0xEF, 0xF3, + 0xFF, 0xFF, 0xFC, 0xFF, 0xFF, 0xFF, 0x7F, 0xFF, 0xFF, 0xDF, 0xF8, 0x7F, + 0xFF, 0xFC, 0x0F, 0xFF, 0xFE, 0x01, 0xFF, 0xFF, 0x80, 0x7F, 0xFF, 0xE0, + 0x1F, 0xFF, 0xF8, 0x07, 0xFF, 0xFE, 0x01, 0xFF, 0xFF, 0x00, 0x3F, 0xFF, + 0xC0, 0x0F, 0xFF, 0xF0, 0x03, 0xFF, 0xFC, 0x00, 0xFF, 0xFF, 0x00, 0x3F, + 0xFF, 0xC0, 0x0F, 0xFF, 0xF0, 0x03, 0xFF, 0xFC, 0x00, 0xFF, 0xFF, 0x00, + 0x3F, 0xFF, 0xC0, 0x0F, 0xFF, 0xF0, 0x03, 0xFF, 0xFC, 0x00, 0xFF, 0xFF, + 0x00, 0x3F, 0xFF, 0xC0, 0x0F, 0xFF, 0xF0, 0x03, 0xFF, 0xFC, 0x00, 0xFF, + 0xFF, 0x00, 0x3F, 0xFF, 0xC0, 0x0F, 0xFF, 0xF0, 0x03, 0xFF, 0xFC, 0x00, + 0xFF, 0xFF, 0x00, 0x3F, 0xFF, 0xC0, 0x0F, 0xFF, 0xF0, 0x03, 0xFF, 0xFC, + 0x00, 0xFF, 0xFF, 0x00, 0x3F, 0xFF, 0xC0, 0x0F, 0xFF, 0xF0, 0x03, 0xFF, + 0xFC, 0x00, 0xFF, 0xFF, 0x00, 0x3F, 0xFF, 0xC0, 0x0F, 0xFF, 0xF0, 0x03, + 0xFF, 0xFE, 0x01, 0xFF, 0xFF, 0x80, 0x7F, 0xFF, 0xE0, 0x1F, 0xFF, 0xF8, + 0x07, 0xFF, 0xFF, 0x03, 0xFF, 0xFF, 0xC0, 0xFF, 0xDF, 0xFF, 0xFF, 0xF7, + 0xFF, 0xFF, 0xFD, 0xFF, 0xFE, 0xFF, 0x3F, 0xFF, 0xBF, 0xC7, 0xFF, 0xCF, + 0xF1, 0xFF, 0xE3, 0xFC, 0x1F, 0xF0, 0xFF, 0x00, 0xE0, 0x00, 0x00, 0x00, + 0x7F, 0xC0, 0x00, 0xFF, 0xFC, 0x00, 0x7F, 0xFF, 0x80, 0x3F, 0xFF, 0xF0, + 0x1F, 0xFF, 0xFE, 0x0F, 0xFF, 0xFF, 0xC3, 0xFF, 0xFF, 0xF1, 0xFF, 0x87, + 0xFE, 0x7F, 0xC0, 0xFF, 0xBF, 0xE0, 0x1F, 0xEF, 0xF8, 0x07, 0xFB, 0xFE, + 0x01, 0xFF, 0xFF, 0x80, 0x7F, 0xFF, 0xC0, 0x1F, 0xFF, 0xF0, 0x07, 0xFF, + 0xFC, 0x01, 0xFF, 0xFF, 0x00, 0x7F, 0xFF, 0xC0, 0x1F, 0xFF, 0xF0, 0x07, + 0xFF, 0xFC, 0x01, 0xFF, 0xFF, 0x00, 0x7F, 0xFF, 0xC0, 0x1F, 0xFF, 0xF0, + 0x07, 0xFF, 0xFC, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xF0, 0x00, 0x03, 0xFC, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x3F, 0xC0, + 0x00, 0x0F, 0xF0, 0x00, 0x03, 0xFC, 0x00, 0x00, 0xFF, 0x00, 0x7F, 0xFF, + 0xC0, 0x1F, 0xFF, 0xF0, 0x07, 0xFF, 0xFC, 0x01, 0xFF, 0xFF, 0x00, 0x7F, + 0xFF, 0xC0, 0x1F, 0xFF, 0xF0, 0x07, 0xFF, 0xFC, 0x01, 0xFF, 0xFF, 0x00, + 0x7F, 0xFF, 0xE0, 0x1F, 0xFF, 0xF8, 0x07, 0xFB, 0xFE, 0x01, 0xFE, 0xFF, + 0x80, 0x7F, 0x9F, 0xE0, 0x3F, 0xE7, 0xFC, 0x0F, 0xF9, 0xFF, 0xFF, 0xFC, + 0x3F, 0xFF, 0xFF, 0x0F, 0xFF, 0xFF, 0xC1, 0xFF, 0xFF, 0xE0, 0x3F, 0xFF, + 0xF0, 0x07, 0xFF, 0xF8, 0x00, 0xFF, 0xF8, 0x00, 0x01, 0xE0, 0x00, 0x00, + 0x7F, 0xE0, 0x0F, 0xFF, 0x01, 0xFF, 0xF0, 0x3F, 0xFF, 0x07, 0xFF, 0xF0, + 0x7F, 0xFF, 0x07, 0xFE, 0x00, 0x7F, 0xC0, 0x0F, 0xF8, 0x00, 0xFF, 0x80, + 0x0F, 0xF8, 0x00, 0xFF, 0x80, 0x0F, 0xF8, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0xFF, + 0x80, 0x0F, 0xF8, 0x00, 0xFF, 0x80, 0x0F, 0xF8, 0x00, 0xFF, 0x80, 0x0F, + 0xF8, 0x00, 0xFF, 0x80, 0x0F, 0xF8, 0x00, 0xFF, 0x80, 0x0F, 0xF8, 0x00, + 0xFF, 0x80, 0x0F, 0xF8, 0x00, 0xFF, 0x80, 0x0F, 0xF8, 0x00, 0xFF, 0x80, + 0x0F, 0xF8, 0x00, 0xFF, 0x80, 0x0F, 0xF8, 0x00, 0xFF, 0x80, 0x0F, 0xF8, + 0x00, 0xFF, 0x80, 0x0F, 0xF8, 0x00, 0xFF, 0x80, 0x0F, 0xF8, 0x00, 0xFF, + 0x80, 0x0F, 0xF8, 0x00, 0xFF, 0x80, 0x0F, 0xF8, 0x00, 0xFF, 0x80, 0x0F, + 0xF8, 0x00, 0xFF, 0x80, 0x0F, 0xF8, 0x00, 0xFF, 0x80, 0x0F, 0xF8, 0x00, + 0xFF, 0x80, 0x0F, 0xF8, 0x00, 0xFF, 0x80, 0x0F, 0xF8, 0x00, 0xFF, 0x80, + 0x0F, 0xF8, 0x00, 0xFF, 0x80, 0x0F, 0xF8, 0x00, 0xFF, 0x80, 0x0F, 0xF8, + 0x00, 0xFF, 0x80, 0x0F, 0xF8, 0x00, 0xFF, 0x80, 0x0F, 0xF8, 0x00, 0xFF, + 0x80, 0x00, 0xFC, 0x00, 0x00, 0x7F, 0xE3, 0xFC, 0x1F, 0xFE, 0x7F, 0x87, + 0xFF, 0xEF, 0xF1, 0xFF, 0xFD, 0xFE, 0x3F, 0xFF, 0xFF, 0xCF, 0xFF, 0xFF, + 0xF9, 0xFF, 0x87, 0xFF, 0x3F, 0xE0, 0x7F, 0xEF, 0xF8, 0x07, 0xFD, 0xFF, + 0x00, 0xFF, 0xBF, 0xE0, 0x1F, 0xF7, 0xFC, 0x03, 0xFE, 0xFF, 0x00, 0x7F, + 0xDF, 0xE0, 0x0F, 0xFB, 0xFC, 0x00, 0xFF, 0x7F, 0x80, 0x1F, 0xEF, 0xF0, + 0x03, 0xFD, 0xFE, 0x00, 0x7F, 0xBF, 0xC0, 0x0F, 0xF7, 0xF8, 0x01, 0xFE, + 0xFF, 0x00, 0x3F, 0xDF, 0xE0, 0x07, 0xFB, 0xFC, 0x00, 0xFF, 0x7F, 0x80, + 0x1F, 0xEF, 0xF0, 0x03, 0xFD, 0xFE, 0x00, 0x7F, 0xBF, 0xC0, 0x0F, 0xF7, + 0xF8, 0x01, 0xFE, 0xFF, 0x00, 0x3F, 0xDF, 0xE0, 0x07, 0xFB, 0xFC, 0x00, + 0xFF, 0x7F, 0x80, 0x1F, 0xEF, 0xF0, 0x03, 0xFD, 0xFE, 0x00, 0x7F, 0xBF, + 0xC0, 0x0F, 0xF7, 0xF8, 0x01, 0xFE, 0xFF, 0x00, 0x7F, 0xDF, 0xF0, 0x0F, + 0xFB, 0xFE, 0x01, 0xFF, 0x7F, 0xC0, 0x3F, 0xEF, 0xF8, 0x07, 0xFD, 0xFF, + 0x00, 0xFF, 0xBF, 0xF0, 0x1F, 0xF3, 0xFE, 0x07, 0xFE, 0x7F, 0xF3, 0xFF, + 0xCF, 0xFF, 0xFF, 0xF8, 0xFF, 0xFF, 0xFF, 0x1F, 0xFF, 0xDF, 0xE1, 0xFF, + 0xFB, 0xFC, 0x1F, 0xFE, 0x7F, 0x81, 0xFF, 0x0F, 0xF0, 0x00, 0x01, 0xFE, + 0x00, 0x00, 0x3F, 0xC0, 0x00, 0x0F, 0xF8, 0x00, 0x01, 0xFF, 0x00, 0x00, + 0x3F, 0xE2, 0x00, 0x0F, 0xFC, 0x70, 0x01, 0xFF, 0x1F, 0xC0, 0xFF, 0xE7, + 0xFF, 0xFF, 0xF8, 0xFF, 0xFF, 0xFF, 0x3F, 0xFF, 0xFF, 0xC3, 0xFF, 0xFF, + 0xF0, 0x1F, 0xFF, 0xFC, 0x00, 0xFF, 0xFE, 0x00, 0x01, 0xF8, 0x00, 0x00, + 0xFF, 0x80, 0x00, 0x0F, 0xF8, 0x00, 0x00, 0xFF, 0x80, 0x00, 0x0F, 0xF8, + 0x00, 0x00, 0xFF, 0x80, 0x00, 0x0F, 0xF8, 0x00, 0x00, 0xFF, 0x80, 0x00, + 0x0F, 0xF8, 0x00, 0x00, 0xFF, 0x80, 0x00, 0x0F, 0xF8, 0x00, 0x00, 0xFF, + 0x81, 0xFC, 0x0F, 0xF8, 0x7F, 0xF0, 0xFF, 0x8F, 0xFF, 0x8F, 0xF9, 0xFF, + 0xFC, 0xFF, 0xBF, 0xFF, 0xCF, 0xFB, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xEF, + 0xFF, 0x9F, 0xFE, 0xFF, 0xE0, 0x3F, 0xEF, 0xFC, 0x03, 0xFF, 0xFF, 0xC0, + 0x1F, 0xFF, 0xFC, 0x01, 0xFF, 0xFF, 0x80, 0x1F, 0xFF, 0xF8, 0x01, 0xFF, + 0xFF, 0x80, 0x1F, 0xFF, 0xF8, 0x01, 0xFF, 0xFF, 0x80, 0x1F, 0xFF, 0xF8, + 0x01, 0xFF, 0xFF, 0x80, 0x1F, 0xFF, 0xF8, 0x01, 0xFF, 0xFF, 0x80, 0x1F, + 0xFF, 0xF8, 0x01, 0xFF, 0xFF, 0x80, 0x1F, 0xFF, 0xF8, 0x01, 0xFF, 0xFF, + 0x80, 0x1F, 0xFF, 0xF8, 0x01, 0xFF, 0xFF, 0x80, 0x1F, 0xFF, 0xF8, 0x01, + 0xFF, 0xFF, 0x80, 0x1F, 0xFF, 0xF8, 0x01, 0xFF, 0xFF, 0x80, 0x1F, 0xFF, + 0xF8, 0x01, 0xFF, 0xFF, 0x80, 0x1F, 0xFF, 0xF8, 0x01, 0xFF, 0xFF, 0x80, + 0x1F, 0xFF, 0xF8, 0x01, 0xFF, 0xFF, 0x80, 0x1F, 0xFF, 0xF8, 0x01, 0xFF, + 0xFF, 0x80, 0x1F, 0xFF, 0xF8, 0x01, 0xFF, 0xFF, 0x80, 0x1F, 0xFF, 0xF8, + 0x01, 0xFF, 0xFF, 0x80, 0x1F, 0xFF, 0xF8, 0x01, 0xFF, 0xFF, 0x80, 0x1F, + 0xFF, 0xF8, 0x01, 0xFF, 0xFF, 0x80, 0x1F, 0xFF, 0xF8, 0x01, 0xFF, 0xFF, + 0x80, 0x1F, 0xFF, 0xF8, 0x01, 0xFF, 0xFF, 0x80, 0x1F, 0xFF, 0xF8, 0x01, + 0xFF, 0xFF, 0x80, 0x1F, 0xFF, 0xF8, 0x01, 0xFF, 0xFF, 0x80, 0x1F, 0xFF, + 0xF8, 0x01, 0xFF, 0xFF, 0x80, 0x1F, 0xFF, 0xF8, 0x01, 0xFF, 0x7F, 0xDF, + 0xF7, 0xFD, 0xFF, 0x7F, 0xDF, 0xF7, 0xFD, 0xFF, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x0F, 0xFB, 0xFE, 0xFF, 0xBF, 0xEF, 0xFB, 0xFE, 0xFF, + 0xBF, 0xEF, 0xFB, 0xFE, 0xFF, 0xBF, 0xEF, 0xFB, 0xFE, 0xFF, 0xBF, 0xEF, + 0xFB, 0xFE, 0xFF, 0xBF, 0xEF, 0xFB, 0xFE, 0xFF, 0xBF, 0xEF, 0xFB, 0xFE, + 0xFF, 0xBF, 0xEF, 0xFB, 0xFE, 0xFF, 0xBF, 0xEF, 0xFB, 0xFE, 0xFF, 0xBF, + 0xEF, 0xFB, 0xFE, 0xFF, 0xBF, 0xEF, 0xFB, 0xFE, 0xFF, 0xBF, 0xEF, 0xFB, + 0xFE, 0xFF, 0xBF, 0xEF, 0xFB, 0xFE, 0xFF, 0xBF, 0xEF, 0xFB, 0xFE, 0xFF, + 0xBF, 0xEF, 0xF8, 0x07, 0xFC, 0x1F, 0xF0, 0x7F, 0xC1, 0xFF, 0x07, 0xFC, + 0x1F, 0xF0, 0x7F, 0xC1, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xFF, 0x83, 0xFE, 0x0F, 0xF8, 0x3F, 0xE0, 0xFF, + 0x83, 0xFE, 0x0F, 0xF8, 0x3F, 0xE0, 0xFF, 0x83, 0xFE, 0x0F, 0xF8, 0x3F, + 0xE0, 0xFF, 0x83, 0xFE, 0x0F, 0xF8, 0x3F, 0xE0, 0xFF, 0x83, 0xFE, 0x0F, + 0xF8, 0x3F, 0xE0, 0xFF, 0x83, 0xFE, 0x0F, 0xF8, 0x3F, 0xE0, 0xFF, 0x83, + 0xFE, 0x0F, 0xF8, 0x3F, 0xE0, 0xFF, 0x83, 0xFE, 0x0F, 0xF8, 0x3F, 0xE0, + 0xFF, 0x83, 0xFE, 0x0F, 0xF8, 0x3F, 0xE0, 0xFF, 0x83, 0xFE, 0x0F, 0xF8, + 0x3F, 0xE0, 0xFF, 0x83, 0xFE, 0x0F, 0xF8, 0x3F, 0xE0, 0xFF, 0x83, 0xFE, + 0x0F, 0xF8, 0x3F, 0xE0, 0xFF, 0x83, 0xFE, 0x0F, 0xF8, 0x3F, 0xE0, 0xFF, + 0x83, 0xFE, 0x0F, 0xF8, 0x3F, 0xE0, 0xFF, 0x83, 0xFE, 0xFF, 0xFB, 0xFF, + 0xEF, 0xFF, 0x3F, 0xFC, 0xFF, 0xE3, 0xFF, 0x07, 0xF0, 0x00, 0xFF, 0x80, + 0x00, 0x03, 0xFE, 0x00, 0x00, 0x0F, 0xF8, 0x00, 0x00, 0x3F, 0xE0, 0x00, + 0x00, 0xFF, 0x80, 0x00, 0x03, 0xFE, 0x00, 0x00, 0x0F, 0xF8, 0x00, 0x00, + 0x3F, 0xE0, 0x00, 0x00, 0xFF, 0x80, 0x00, 0x03, 0xFE, 0x00, 0x00, 0x0F, + 0xF8, 0x00, 0x00, 0x3F, 0xE0, 0x03, 0xFE, 0xFF, 0x80, 0x1F, 0xF3, 0xFE, + 0x00, 0x7F, 0xCF, 0xF8, 0x03, 0xFE, 0x3F, 0xE0, 0x0F, 0xF8, 0xFF, 0x80, + 0x3F, 0xC3, 0xFE, 0x01, 0xFF, 0x0F, 0xF8, 0x07, 0xFC, 0x3F, 0xE0, 0x3F, + 0xE0, 0xFF, 0x80, 0xFF, 0x83, 0xFE, 0x03, 0xFC, 0x0F, 0xF8, 0x1F, 0xF0, + 0x3F, 0xE0, 0x7F, 0xC0, 0xFF, 0x83, 0xFE, 0x03, 0xFE, 0x0F, 0xF8, 0x0F, + 0xF8, 0x3F, 0xC0, 0x3F, 0xE1, 0xFF, 0x00, 0xFF, 0x87, 0xFC, 0x03, 0xFE, + 0x3F, 0xE0, 0x0F, 0xF8, 0xFF, 0x80, 0x3F, 0xE3, 0xFC, 0x00, 0xFF, 0x9F, + 0xF0, 0x03, 0xFE, 0x7F, 0x80, 0x0F, 0xFB, 0xFE, 0x00, 0x3F, 0xEF, 0xF8, + 0x00, 0xFF, 0xBF, 0xC0, 0x03, 0xFF, 0xFF, 0x00, 0x0F, 0xFF, 0xF8, 0x00, + 0x3F, 0xFF, 0xE0, 0x00, 0xFF, 0xFF, 0xC0, 0x03, 0xFE, 0xFF, 0x00, 0x0F, + 0xFB, 0xFE, 0x00, 0x3F, 0xE7, 0xF8, 0x00, 0xFF, 0x9F, 0xF0, 0x03, 0xFE, + 0x7F, 0xC0, 0x0F, 0xF8, 0xFF, 0x00, 0x3F, 0xE3, 0xFE, 0x00, 0xFF, 0x87, + 0xF8, 0x03, 0xFE, 0x1F, 0xF0, 0x0F, 0xF8, 0x7F, 0xC0, 0x3F, 0xE0, 0xFF, + 0x80, 0xFF, 0x83, 0xFE, 0x03, 0xFE, 0x07, 0xF8, 0x0F, 0xF8, 0x1F, 0xF0, + 0x3F, 0xE0, 0x7F, 0xC0, 0xFF, 0x80, 0xFF, 0x83, 0xFE, 0x03, 0xFE, 0x0F, + 0xF8, 0x07, 0xF8, 0x3F, 0xE0, 0x1F, 0xF0, 0xFF, 0x80, 0x7F, 0xC3, 0xFE, + 0x00, 0xFF, 0x8F, 0xF8, 0x03, 0xFE, 0x3F, 0xE0, 0x07, 0xFC, 0xFF, 0x80, + 0x1F, 0xF3, 0xFE, 0x00, 0x7F, 0xCF, 0xF8, 0x00, 0xFF, 0xBF, 0xE0, 0x03, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x01, 0xFC, 0x00, 0xFF, 0x03, + 0xFE, 0x1F, 0xF8, 0x0F, 0xFF, 0x0F, 0xF9, 0xFF, 0xF8, 0x7F, 0xFE, 0x3F, + 0xE7, 0xFF, 0xE3, 0xFF, 0xFC, 0xFF, 0xBF, 0xFF, 0xDF, 0xFF, 0xF3, 0xFF, + 0xFF, 0xFF, 0x7F, 0xFF, 0xEF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xBF, 0xFF, + 0x7F, 0xFF, 0xCF, 0xFE, 0xFF, 0xE0, 0x7F, 0xF8, 0x0F, 0xFB, 0xFF, 0x00, + 0xFF, 0xC0, 0x3F, 0xFF, 0xFC, 0x03, 0xFF, 0x00, 0x7F, 0xFF, 0xE0, 0x07, + 0xFC, 0x01, 0xFF, 0xFF, 0x80, 0x1F, 0xF0, 0x07, 0xFF, 0xFE, 0x00, 0x7F, + 0x80, 0x1F, 0xFF, 0xF8, 0x01, 0xFE, 0x00, 0x7F, 0xFF, 0xE0, 0x07, 0xF8, + 0x01, 0xFF, 0xFF, 0x80, 0x1F, 0xE0, 0x07, 0xFF, 0xFE, 0x00, 0x7F, 0x80, + 0x1F, 0xFF, 0xF8, 0x01, 0xFE, 0x00, 0x7F, 0xFF, 0xE0, 0x07, 0xF8, 0x01, + 0xFF, 0xFF, 0x80, 0x1F, 0xE0, 0x07, 0xFF, 0xFE, 0x00, 0x7F, 0x80, 0x1F, + 0xFF, 0xF8, 0x01, 0xFE, 0x00, 0x7F, 0xFF, 0xE0, 0x07, 0xF8, 0x01, 0xFF, + 0xFF, 0x80, 0x1F, 0xE0, 0x07, 0xFF, 0xFE, 0x00, 0x7F, 0x80, 0x1F, 0xFF, + 0xF8, 0x01, 0xFE, 0x00, 0x7F, 0xFF, 0xE0, 0x07, 0xF8, 0x01, 0xFF, 0xFF, + 0x80, 0x1F, 0xE0, 0x07, 0xFF, 0xFE, 0x00, 0x7F, 0x80, 0x1F, 0xFF, 0xF8, + 0x01, 0xFE, 0x00, 0x7F, 0xFF, 0xE0, 0x07, 0xF8, 0x01, 0xFF, 0xFF, 0x80, + 0x1F, 0xE0, 0x07, 0xFF, 0xFE, 0x00, 0x7F, 0x80, 0x1F, 0xFF, 0xF8, 0x01, + 0xFE, 0x00, 0x7F, 0xFF, 0xE0, 0x07, 0xF8, 0x01, 0xFF, 0xFF, 0x80, 0x1F, + 0xE0, 0x07, 0xFF, 0xFE, 0x00, 0x7F, 0x80, 0x1F, 0xFF, 0xF8, 0x01, 0xFE, + 0x00, 0x7F, 0xFF, 0xE0, 0x07, 0xF8, 0x01, 0xFF, 0xFF, 0x80, 0x1F, 0xE0, + 0x07, 0xFF, 0xFE, 0x00, 0x7F, 0x80, 0x1F, 0xFF, 0xF8, 0x01, 0xFE, 0x00, + 0x7F, 0xFF, 0xE0, 0x07, 0xF8, 0x01, 0xFF, 0xFF, 0x80, 0x1F, 0xE0, 0x07, + 0xFF, 0xFE, 0x00, 0x7F, 0x80, 0x1F, 0xFF, 0xF8, 0x01, 0xFE, 0x00, 0x7F, + 0xFF, 0xE0, 0x07, 0xF8, 0x01, 0xFF, 0xFF, 0x80, 0x1F, 0xE0, 0x07, 0xFF, + 0xFE, 0x00, 0x7F, 0x80, 0x1F, 0xFF, 0xF8, 0x01, 0xFE, 0x00, 0x7F, 0xFF, + 0xE0, 0x07, 0xF8, 0x01, 0xFF, 0xFF, 0x80, 0x1F, 0xE0, 0x07, 0xFF, 0xFE, + 0x00, 0x7F, 0x80, 0x1F, 0xFF, 0xF8, 0x01, 0xFE, 0x00, 0x7F, 0xFF, 0xE0, + 0x07, 0xF8, 0x01, 0xFF, 0xFF, 0x80, 0x1F, 0xE0, 0x07, 0xFF, 0xFE, 0x00, + 0x7F, 0x80, 0x1F, 0xF0, 0x00, 0x01, 0xFC, 0x0F, 0xF8, 0x7F, 0xF0, 0xFF, + 0x8F, 0xFF, 0x8F, 0xF9, 0xFF, 0xFC, 0xFF, 0xBF, 0xFF, 0xCF, 0xFB, 0xFF, + 0xFE, 0xFF, 0xFF, 0xFF, 0xEF, 0xFF, 0x8F, 0xFE, 0xFF, 0xE0, 0x3F, 0xEF, + 0xFC, 0x03, 0xFF, 0xFF, 0xC0, 0x1F, 0xFF, 0xF8, 0x01, 0xFF, 0xFF, 0x80, + 0x1F, 0xFF, 0xF8, 0x01, 0xFF, 0xFF, 0x80, 0x1F, 0xFF, 0xF8, 0x01, 0xFF, + 0xFF, 0x80, 0x1F, 0xFF, 0xF8, 0x01, 0xFF, 0xFF, 0x80, 0x1F, 0xFF, 0xF8, + 0x01, 0xFF, 0xFF, 0x80, 0x1F, 0xFF, 0xF8, 0x01, 0xFF, 0xFF, 0x80, 0x1F, + 0xFF, 0xF8, 0x01, 0xFF, 0xFF, 0x80, 0x1F, 0xFF, 0xF8, 0x01, 0xFF, 0xFF, + 0x80, 0x1F, 0xFF, 0xF8, 0x01, 0xFF, 0xFF, 0x80, 0x1F, 0xFF, 0xF8, 0x01, + 0xFF, 0xFF, 0x80, 0x1F, 0xFF, 0xF8, 0x01, 0xFF, 0xFF, 0x80, 0x1F, 0xFF, + 0xF8, 0x01, 0xFF, 0xFF, 0x80, 0x1F, 0xFF, 0xF8, 0x01, 0xFF, 0xFF, 0x80, + 0x1F, 0xFF, 0xF8, 0x01, 0xFF, 0xFF, 0x80, 0x1F, 0xFF, 0xF8, 0x01, 0xFF, + 0xFF, 0x80, 0x1F, 0xFF, 0xF8, 0x01, 0xFF, 0xFF, 0x80, 0x1F, 0xFF, 0xF8, + 0x01, 0xFF, 0xFF, 0x80, 0x1F, 0xFF, 0xF8, 0x01, 0xFF, 0xFF, 0x80, 0x1F, + 0xFF, 0xF8, 0x01, 0xFF, 0xFF, 0x80, 0x1F, 0xFF, 0xF8, 0x01, 0xFF, 0xFF, + 0x80, 0x1F, 0xFF, 0xF8, 0x01, 0xFF, 0xFF, 0x80, 0x1F, 0xFF, 0xF8, 0x01, + 0xFF, 0xFF, 0x80, 0x1F, 0xFF, 0xF8, 0x01, 0xFF, 0xFF, 0x80, 0x1F, 0xFF, + 0xF8, 0x01, 0xFF, 0x00, 0x7F, 0x80, 0x00, 0xFF, 0xFC, 0x00, 0x7F, 0xFF, + 0x80, 0x3F, 0xFF, 0xF0, 0x1F, 0xFF, 0xFE, 0x0F, 0xFF, 0xFF, 0xC3, 0xFF, + 0xFF, 0xF1, 0xFF, 0x87, 0xFE, 0x7F, 0xC0, 0xFF, 0x9F, 0xE0, 0x3F, 0xEF, + 0xF8, 0x07, 0xFF, 0xFE, 0x01, 0xFF, 0xFF, 0x80, 0x7F, 0xFF, 0xE0, 0x1F, + 0xFF, 0xF0, 0x07, 0xFF, 0xFC, 0x01, 0xFF, 0xFF, 0x00, 0x7F, 0xFF, 0xC0, + 0x1F, 0xFF, 0xF0, 0x07, 0xFF, 0xFC, 0x01, 0xFF, 0xFF, 0x00, 0x7F, 0xFF, + 0xC0, 0x1F, 0xFF, 0xF0, 0x07, 0xFF, 0xFC, 0x01, 0xFF, 0xFF, 0x00, 0x7F, + 0xFF, 0xC0, 0x1F, 0xFF, 0xF0, 0x07, 0xFF, 0xFC, 0x01, 0xFF, 0xFF, 0x00, + 0x7F, 0xFF, 0xC0, 0x1F, 0xFF, 0xF0, 0x07, 0xFF, 0xFC, 0x01, 0xFF, 0xFF, + 0x00, 0x7F, 0xFF, 0xC0, 0x1F, 0xFF, 0xF0, 0x07, 0xFF, 0xFC, 0x01, 0xFF, + 0xFF, 0x00, 0x7F, 0xFF, 0xC0, 0x1F, 0xFF, 0xF0, 0x07, 0xFF, 0xFC, 0x01, + 0xFF, 0xFF, 0x00, 0x7F, 0xFF, 0xC0, 0x1F, 0xFF, 0xF0, 0x07, 0xFF, 0xFC, + 0x01, 0xFF, 0xFF, 0x00, 0x7F, 0xFF, 0xE0, 0x1F, 0xFF, 0xF8, 0x07, 0xFF, + 0xFE, 0x01, 0xFF, 0xFF, 0x80, 0x7F, 0xDF, 0xF0, 0x3F, 0xE7, 0xFC, 0x0F, + 0xF9, 0xFF, 0xFF, 0xFE, 0x3F, 0xFF, 0xFF, 0x0F, 0xFF, 0xFF, 0xC1, 0xFF, + 0xFF, 0xE0, 0x3F, 0xFF, 0xF0, 0x07, 0xFF, 0xF8, 0x00, 0x7F, 0xF8, 0x00, + 0x01, 0xE0, 0x00, 0x00, 0x01, 0xF0, 0x1F, 0xF1, 0xFF, 0xC3, 0xFE, 0x7F, + 0xFC, 0x7F, 0xDF, 0xFF, 0x8F, 0xFB, 0xFF, 0xF9, 0xFF, 0xFF, 0xFF, 0xBF, + 0xFF, 0xFF, 0xF7, 0xFF, 0x87, 0xFE, 0xFF, 0xE0, 0x7F, 0xDF, 0xF8, 0x07, + 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xE0, 0x1F, 0xFF, 0xF8, 0x03, 0xFF, 0xFF, + 0x00, 0x7F, 0xFF, 0xE0, 0x0F, 0xFF, 0xFC, 0x01, 0xFF, 0xFF, 0x80, 0x3F, + 0xFF, 0xF0, 0x07, 0xFF, 0xFE, 0x00, 0xFF, 0xFF, 0xC0, 0x1F, 0xFF, 0xF8, + 0x03, 0xFF, 0xFF, 0x00, 0x7F, 0xFF, 0xE0, 0x0F, 0xFF, 0xFC, 0x01, 0xFF, + 0xFF, 0x80, 0x3F, 0xFF, 0xF0, 0x07, 0xFF, 0xFE, 0x00, 0xFF, 0xFF, 0xC0, + 0x1F, 0xFF, 0xF8, 0x03, 0xFF, 0xFF, 0x00, 0x7F, 0xFF, 0xE0, 0x0F, 0xFF, + 0xFC, 0x01, 0xFF, 0xFF, 0x80, 0x3F, 0xFF, 0xF0, 0x07, 0xFF, 0xFE, 0x00, + 0xFF, 0xFF, 0xC0, 0x1F, 0xFF, 0xF8, 0x03, 0xFF, 0xFF, 0x00, 0x7F, 0xFF, + 0xE0, 0x0F, 0xFF, 0xFC, 0x01, 0xFF, 0xFF, 0x80, 0x3F, 0xFF, 0xF0, 0x07, + 0xFF, 0xFE, 0x00, 0xFF, 0xFF, 0xC0, 0x1F, 0xFF, 0xF8, 0x03, 0xFF, 0xFF, + 0x00, 0x7F, 0xFF, 0xF0, 0x0F, 0xFF, 0xFE, 0x01, 0xFF, 0xFF, 0xC0, 0x3F, + 0xFF, 0xF8, 0x0F, 0xFB, 0xFF, 0x81, 0xFF, 0x7F, 0xFF, 0xFF, 0xEF, 0xFF, + 0xFF, 0xFD, 0xFF, 0xFF, 0xFF, 0x3F, 0xFF, 0xFF, 0xE7, 0xFD, 0xFF, 0xF8, + 0xFF, 0x9F, 0xFE, 0x1F, 0xF1, 0xFF, 0x03, 0xFE, 0x07, 0x00, 0x7F, 0xC0, + 0x00, 0x0F, 0xF8, 0x00, 0x01, 0xFF, 0x00, 0x00, 0x3F, 0xE0, 0x00, 0x07, + 0xFC, 0x00, 0x00, 0xFF, 0x80, 0x00, 0x1F, 0xF0, 0x00, 0x03, 0xFE, 0x00, + 0x00, 0x7F, 0xC0, 0x00, 0x0F, 0xF8, 0x00, 0x00, 0x01, 0xF0, 0x00, 0x01, + 0xFF, 0x8F, 0xF1, 0xFF, 0xF3, 0xFC, 0x7F, 0xFE, 0xFF, 0x3F, 0xFF, 0xBF, + 0xDF, 0xFF, 0xFF, 0xF7, 0xFF, 0xFF, 0xFD, 0xFF, 0x8F, 0xFF, 0xFF, 0xC0, + 0xFF, 0xFF, 0xE0, 0x3F, 0xFF, 0xF8, 0x07, 0xFF, 0xFE, 0x01, 0xFF, 0xFF, + 0x80, 0x7F, 0xFF, 0xE0, 0x1F, 0xFF, 0xF0, 0x07, 0xFF, 0xFC, 0x01, 0xFF, + 0xFF, 0x00, 0x3F, 0xFF, 0xC0, 0x0F, 0xFF, 0xF0, 0x03, 0xFF, 0xFC, 0x00, + 0xFF, 0xFF, 0x00, 0x3F, 0xFF, 0xC0, 0x0F, 0xFF, 0xF0, 0x03, 0xFF, 0xFC, + 0x00, 0xFF, 0xFF, 0x00, 0x3F, 0xFF, 0xC0, 0x0F, 0xFF, 0xF0, 0x03, 0xFF, + 0xFC, 0x00, 0xFF, 0xFF, 0x00, 0x3F, 0xFF, 0xC0, 0x0F, 0xFF, 0xF0, 0x03, + 0xFF, 0xFC, 0x00, 0xFF, 0xFF, 0x00, 0x3F, 0xFF, 0xC0, 0x0F, 0xFF, 0xF0, + 0x03, 0xFF, 0xFC, 0x00, 0xFF, 0xFF, 0x00, 0x3F, 0xFF, 0xC0, 0x0F, 0xFF, + 0xF0, 0x03, 0xFF, 0xFC, 0x00, 0xFF, 0xFF, 0x00, 0x3F, 0xFF, 0xC0, 0x0F, + 0xFF, 0xF0, 0x07, 0xFF, 0xFC, 0x01, 0xFF, 0xFF, 0x00, 0x7F, 0xFF, 0xE0, + 0x1F, 0xFF, 0xF8, 0x07, 0xFF, 0xFE, 0x01, 0xFF, 0xFF, 0x80, 0x7F, 0xFF, + 0xE0, 0x3F, 0xF7, 0xFC, 0x1F, 0xFD, 0xFF, 0xFF, 0xFF, 0x7F, 0xFF, 0xFF, + 0xCF, 0xFF, 0xFF, 0xF3, 0xFF, 0xFB, 0xFC, 0x7F, 0xFE, 0xFF, 0x0F, 0xFF, + 0x3F, 0xC1, 0xFF, 0x8F, 0xF0, 0x0F, 0x03, 0xFC, 0x00, 0x00, 0xFF, 0x00, + 0x00, 0x3F, 0xC0, 0x00, 0x0F, 0xF0, 0x00, 0x03, 0xFC, 0x00, 0x00, 0xFF, + 0x00, 0x00, 0x3F, 0xC0, 0x00, 0x0F, 0xF0, 0x00, 0x03, 0xFC, 0x00, 0x00, + 0xFF, 0x00, 0x00, 0x3F, 0xC0, 0x00, 0x01, 0xFF, 0xF0, 0xFF, 0xFE, 0x3F, + 0xFF, 0xCF, 0xFF, 0xFB, 0xFF, 0xFF, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, + 0xFF, 0xF8, 0x1F, 0xFC, 0x03, 0xFF, 0x00, 0x7F, 0xC0, 0x0F, 0xF8, 0x01, + 0xFF, 0x00, 0x3F, 0xE0, 0x07, 0xFC, 0x00, 0xFF, 0x80, 0x1F, 0xF0, 0x03, + 0xFE, 0x00, 0x7F, 0xC0, 0x0F, 0xF8, 0x01, 0xFF, 0x00, 0x3F, 0xE0, 0x07, + 0xFC, 0x00, 0xFF, 0x80, 0x1F, 0xF0, 0x03, 0xFE, 0x00, 0x7F, 0xC0, 0x0F, + 0xF8, 0x01, 0xFF, 0x00, 0x3F, 0xE0, 0x07, 0xFC, 0x00, 0xFF, 0x80, 0x1F, + 0xF0, 0x03, 0xFE, 0x00, 0x7F, 0xC0, 0x0F, 0xF8, 0x01, 0xFF, 0x00, 0x3F, + 0xE0, 0x07, 0xFC, 0x00, 0xFF, 0x80, 0x1F, 0xF0, 0x03, 0xFE, 0x00, 0x7F, + 0xC0, 0x0F, 0xF8, 0x01, 0xFF, 0x00, 0x3F, 0xE0, 0x07, 0xFC, 0x00, 0xFF, + 0x80, 0x1F, 0xF0, 0x03, 0xFE, 0x00, 0x7F, 0xC0, 0x0F, 0xF8, 0x01, 0xFF, + 0x00, 0x3F, 0xE0, 0x07, 0xFC, 0x00, 0xFF, 0x80, 0x1F, 0xF0, 0x00, 0x00, + 0x7F, 0x80, 0x00, 0xFF, 0xFC, 0x00, 0xFF, 0xFF, 0x80, 0x7F, 0xFF, 0xF0, + 0x1F, 0xFF, 0xFE, 0x0F, 0xFF, 0xFF, 0x87, 0xFF, 0xFF, 0xF1, 0xFF, 0xCF, + 0xFC, 0x7F, 0xC0, 0xFF, 0x1F, 0xE0, 0x3F, 0xEF, 0xF8, 0x07, 0xFB, 0xFE, + 0x01, 0xFE, 0xFF, 0x80, 0x7F, 0xBF, 0xE0, 0x1F, 0xEF, 0xF8, 0x07, 0xFB, + 0xFE, 0x01, 0xFE, 0xFF, 0x80, 0x7F, 0x9F, 0xE0, 0x1F, 0xE7, 0xFC, 0x07, + 0xF9, 0xFF, 0x01, 0xFE, 0x7F, 0xE0, 0x00, 0x0F, 0xFC, 0x00, 0x03, 0xFF, + 0x80, 0x00, 0x7F, 0xF0, 0x00, 0x0F, 0xFE, 0x00, 0x03, 0xFF, 0xC0, 0x00, + 0x7F, 0xF8, 0x00, 0x0F, 0xFF, 0x00, 0x01, 0xFF, 0xE0, 0x00, 0x3F, 0xFC, + 0x00, 0x07, 0xFF, 0x80, 0x00, 0xFF, 0xF0, 0x00, 0x1F, 0xFE, 0x00, 0x03, + 0xFF, 0x80, 0x00, 0x7F, 0xF0, 0x00, 0x0F, 0xFC, 0x00, 0x01, 0xFF, 0x80, + 0x00, 0x7F, 0xE7, 0xF8, 0x0F, 0xF9, 0xFE, 0x01, 0xFF, 0x7F, 0x80, 0x7F, + 0xDF, 0xE0, 0x1F, 0xF7, 0xF8, 0x07, 0xFD, 0xFE, 0x00, 0xFF, 0x7F, 0x80, + 0x3F, 0xDF, 0xE0, 0x0F, 0xF7, 0xF8, 0x03, 0xFD, 0xFE, 0x01, 0xFF, 0x7F, + 0xC0, 0x7F, 0xDF, 0xF0, 0x1F, 0xF3, 0xFE, 0x0F, 0xFC, 0xFF, 0xFF, 0xFE, + 0x3F, 0xFF, 0xFF, 0x87, 0xFF, 0xFF, 0xC0, 0xFF, 0xFF, 0xF0, 0x3F, 0xFF, + 0xF8, 0x03, 0xFF, 0xFC, 0x00, 0x7F, 0xFC, 0x00, 0x03, 0xF8, 0x00, 0x07, + 0xF8, 0x00, 0x7F, 0x80, 0x07, 0xF8, 0x00, 0x7F, 0x80, 0x07, 0xF8, 0x00, + 0x7F, 0x80, 0x07, 0xF8, 0x00, 0x7F, 0x80, 0x07, 0xF8, 0x00, 0x7F, 0x80, + 0xFF, 0xFF, 0xEF, 0xFF, 0xFE, 0xFF, 0xFF, 0xEF, 0xFF, 0xFE, 0xFF, 0xFF, + 0xEF, 0xFF, 0xFE, 0xFF, 0xFF, 0xE0, 0x7F, 0x80, 0x07, 0xF8, 0x00, 0x7F, + 0x80, 0x07, 0xF8, 0x00, 0x7F, 0x80, 0x07, 0xF8, 0x00, 0x7F, 0x80, 0x07, + 0xF8, 0x00, 0x7F, 0x80, 0x07, 0xF8, 0x00, 0x7F, 0x80, 0x07, 0xF8, 0x00, + 0x7F, 0x80, 0x07, 0xF8, 0x00, 0x7F, 0x80, 0x07, 0xF8, 0x00, 0x7F, 0x80, + 0x07, 0xF8, 0x00, 0x7F, 0x80, 0x07, 0xF8, 0x00, 0x7F, 0x80, 0x07, 0xF8, + 0x00, 0x7F, 0x80, 0x07, 0xF8, 0x00, 0x7F, 0x80, 0x07, 0xF8, 0x00, 0x7F, + 0x80, 0x07, 0xF8, 0x00, 0x7F, 0x80, 0x07, 0xF8, 0x00, 0x7F, 0x80, 0x07, + 0xF8, 0x00, 0x7F, 0x80, 0x07, 0xF8, 0x00, 0x7F, 0x80, 0x07, 0xF8, 0x00, + 0x7F, 0x80, 0x07, 0xF8, 0x00, 0x7F, 0x80, 0x07, 0xF8, 0x00, 0x7F, 0xC0, + 0x07, 0xFC, 0x00, 0x7F, 0xC0, 0x07, 0xFF, 0xF0, 0x7F, 0xFF, 0x07, 0xFF, + 0xF0, 0x7F, 0xFF, 0x03, 0xFF, 0xF0, 0x1F, 0xFF, 0x00, 0xFF, 0xF0, 0xFF, + 0x80, 0x1F, 0xFF, 0xF0, 0x03, 0xFF, 0xFE, 0x00, 0x7F, 0xFF, 0xC0, 0x0F, + 0xFF, 0xF8, 0x01, 0xFF, 0xFF, 0x00, 0x3F, 0xFF, 0xE0, 0x07, 0xFF, 0xFC, + 0x00, 0xFF, 0xFF, 0x80, 0x1F, 0xFF, 0xF0, 0x03, 0xFF, 0xFE, 0x00, 0x7F, + 0xFF, 0xC0, 0x0F, 0xFF, 0xF8, 0x01, 0xFF, 0xFF, 0x00, 0x3F, 0xFF, 0xE0, + 0x07, 0xFF, 0xFC, 0x00, 0xFF, 0xFF, 0x80, 0x1F, 0xFF, 0xF0, 0x03, 0xFF, + 0xFE, 0x00, 0x7F, 0xFF, 0xC0, 0x0F, 0xFF, 0xF8, 0x01, 0xFF, 0xFF, 0x00, + 0x3F, 0xFF, 0xE0, 0x07, 0xFF, 0xFC, 0x00, 0xFF, 0xFF, 0x80, 0x1F, 0xFF, + 0xF0, 0x03, 0xFF, 0xFE, 0x00, 0x7F, 0xFF, 0xC0, 0x0F, 0xFF, 0xF8, 0x01, + 0xFF, 0xFF, 0x00, 0x3F, 0xFF, 0xE0, 0x07, 0xFF, 0xFC, 0x00, 0xFF, 0xFF, + 0x80, 0x1F, 0xFF, 0xF0, 0x03, 0xFF, 0xFE, 0x00, 0x7F, 0xFF, 0xC0, 0x0F, + 0xFF, 0xF8, 0x01, 0xFF, 0xFF, 0x00, 0x3F, 0xFF, 0xE0, 0x07, 0xFF, 0xFC, + 0x00, 0xFF, 0xFF, 0x80, 0x1F, 0xFF, 0xF0, 0x03, 0xFF, 0xFE, 0x00, 0x7F, + 0xFF, 0xC0, 0x0F, 0xFF, 0xF8, 0x03, 0xFF, 0xFF, 0x00, 0x7F, 0xFF, 0xE0, + 0x0F, 0xFF, 0xFC, 0x01, 0xFF, 0xFF, 0xC0, 0x7F, 0xFF, 0xFC, 0x1F, 0xFD, + 0xFF, 0xFF, 0xFF, 0xBF, 0xFF, 0xEF, 0xF7, 0xFF, 0xFD, 0xFE, 0x7F, 0xFF, + 0x3F, 0xC7, 0xFF, 0xE7, 0xF8, 0xFF, 0xF8, 0xFF, 0x07, 0xFE, 0x1F, 0xE0, + 0x1E, 0x00, 0x00, 0xFF, 0x00, 0x1F, 0xFF, 0xE0, 0x03, 0xFF, 0xFC, 0x00, + 0x7F, 0xFF, 0x80, 0x1F, 0xE7, 0xF8, 0x03, 0xFC, 0xFF, 0x00, 0x7F, 0x9F, + 0xE0, 0x0F, 0xF3, 0xFC, 0x01, 0xFE, 0x7F, 0x80, 0x3F, 0xCF, 0xF0, 0x07, + 0xF9, 0xFE, 0x00, 0xFE, 0x1F, 0xE0, 0x1F, 0xC3, 0xFC, 0x07, 0xF8, 0x7F, + 0x80, 0xFF, 0x0F, 0xF0, 0x1F, 0xE1, 0xFE, 0x03, 0xFC, 0x3F, 0xC0, 0x7F, + 0x87, 0xF8, 0x0F, 0xE0, 0x7F, 0x01, 0xFC, 0x0F, 0xF0, 0x3F, 0x81, 0xFE, + 0x07, 0xF0, 0x3F, 0xC1, 0xFE, 0x07, 0xF8, 0x3F, 0xC0, 0xFF, 0x07, 0xF8, + 0x1F, 0xE0, 0xFE, 0x01, 0xFC, 0x1F, 0xC0, 0x3F, 0xC3, 0xF8, 0x07, 0xF8, + 0x7F, 0x00, 0xFF, 0x0F, 0xE0, 0x1F, 0xE3, 0xFC, 0x03, 0xFC, 0x7F, 0x80, + 0x7F, 0x8F, 0xE0, 0x07, 0xF1, 0xFC, 0x00, 0xFE, 0x3F, 0x80, 0x1F, 0xC7, + 0xF0, 0x03, 0xFC, 0xFE, 0x00, 0x7F, 0x9F, 0xC0, 0x0F, 0xF3, 0xF8, 0x01, + 0xFE, 0x7E, 0x00, 0x1F, 0xCF, 0xC0, 0x03, 0xFB, 0xF8, 0x00, 0x7F, 0x7F, + 0x00, 0x0F, 0xEF, 0xE0, 0x01, 0xFD, 0xFC, 0x00, 0x3F, 0xFF, 0x80, 0x07, + 0xFF, 0xE0, 0x00, 0x7F, 0xFC, 0x00, 0x0F, 0xFF, 0x80, 0x01, 0xFF, 0xF0, + 0x00, 0x3F, 0xFE, 0x00, 0x07, 0xFF, 0xC0, 0x00, 0xFF, 0xF8, 0x00, 0x1F, + 0xFE, 0x00, 0x01, 0xFF, 0xC0, 0x00, 0x3F, 0xF8, 0x00, 0x07, 0xFF, 0x00, + 0x00, 0xFF, 0xE0, 0x00, 0xFF, 0x00, 0x7F, 0x80, 0x1F, 0xFF, 0xC0, 0x1F, + 0xE0, 0x07, 0xFF, 0xF0, 0x07, 0xF8, 0x03, 0xFF, 0xFC, 0x01, 0xFE, 0x00, + 0xFF, 0x7F, 0x00, 0xFF, 0xC0, 0x3F, 0xDF, 0xC0, 0x3F, 0xF0, 0x0F, 0xE7, + 0xF0, 0x0F, 0xFC, 0x03, 0xF9, 0xFC, 0x03, 0xFF, 0x00, 0xFE, 0x7F, 0x00, + 0xFF, 0xC0, 0x3F, 0x9F, 0xC0, 0x3F, 0xF0, 0x0F, 0xE7, 0xF8, 0x0F, 0xFE, + 0x03, 0xF9, 0xFE, 0x07, 0xFF, 0x80, 0xFE, 0x3F, 0x81, 0xFF, 0xE0, 0x7F, + 0x8F, 0xE0, 0x7F, 0xF8, 0x1F, 0xC3, 0xF8, 0x1F, 0xBE, 0x07, 0xF0, 0xFE, + 0x07, 0xEF, 0x81, 0xFC, 0x3F, 0x81, 0xFB, 0xE0, 0x7F, 0x0F, 0xE0, 0x7E, + 0xFC, 0x1F, 0xC3, 0xF8, 0x3F, 0xBF, 0x07, 0xF0, 0xFE, 0x0F, 0xCF, 0xC1, + 0xFC, 0x1F, 0xC3, 0xF3, 0xF0, 0x7F, 0x07, 0xF0, 0xFC, 0xFC, 0x1F, 0x81, + 0xFC, 0x3F, 0x1F, 0x0F, 0xE0, 0x7F, 0x0F, 0xC7, 0xC3, 0xF8, 0x1F, 0xC3, + 0xF1, 0xF8, 0xFE, 0x07, 0xF1, 0xF8, 0x7E, 0x3F, 0x81, 0xFC, 0x7E, 0x1F, + 0x8F, 0xE0, 0x7F, 0x1F, 0x87, 0xE3, 0xF8, 0x0F, 0xC7, 0xE1, 0xF8, 0xFE, + 0x03, 0xF1, 0xF8, 0x3E, 0x3F, 0x00, 0xFE, 0x7E, 0x0F, 0x8F, 0xC0, 0x3F, + 0x9F, 0x83, 0xF3, 0xF0, 0x0F, 0xE7, 0xC0, 0xFC, 0xFC, 0x03, 0xFB, 0xF0, + 0x3F, 0x3F, 0x00, 0xFE, 0xFC, 0x0F, 0xDF, 0xC0, 0x3F, 0xBF, 0x03, 0xF7, + 0xF0, 0x07, 0xEF, 0xC0, 0xFD, 0xFC, 0x01, 0xFB, 0xF0, 0x1F, 0x7E, 0x00, + 0x7E, 0xFC, 0x07, 0xFF, 0x80, 0x1F, 0xBE, 0x01, 0xFF, 0xE0, 0x07, 0xFF, + 0x80, 0x7F, 0xF8, 0x01, 0xFF, 0xE0, 0x1F, 0xFE, 0x00, 0x7F, 0xF8, 0x07, + 0xFF, 0x80, 0x1F, 0xFE, 0x01, 0xFF, 0xE0, 0x03, 0xFF, 0x80, 0x7F, 0xF8, + 0x00, 0xFF, 0xC0, 0x0F, 0xFC, 0x00, 0x3F, 0xF0, 0x03, 0xFF, 0x00, 0x0F, + 0xFC, 0x00, 0xFF, 0xC0, 0x03, 0xFF, 0x00, 0x3F, 0xF0, 0x00, 0xFF, 0xC0, + 0x0F, 0xFC, 0x00, 0x3F, 0xF0, 0x03, 0xFF, 0x00, 0x0F, 0xFC, 0x00, 0xFF, + 0xC0, 0x01, 0xFE, 0x00, 0x1F, 0xF0, 0x00, 0x7F, 0x80, 0x07, 0xF8, 0x00, + 0x1F, 0xE0, 0x01, 0xFE, 0x00, 0x07, 0xF8, 0x00, 0x7F, 0x80, 0x01, 0xFE, + 0x00, 0x1F, 0xE0, 0x00, 0x7F, 0x80, 0x1F, 0xF7, 0xF8, 0x01, 0xFE, 0x3F, + 0xC0, 0x1F, 0xE3, 0xFC, 0x01, 0xFC, 0x3F, 0xC0, 0x3F, 0xC1, 0xFE, 0x03, + 0xFC, 0x1F, 0xE0, 0x3F, 0x81, 0xFE, 0x07, 0xF8, 0x0F, 0xF0, 0x7F, 0x80, + 0xFF, 0x07, 0xF0, 0x0F, 0xF0, 0x7F, 0x00, 0x7F, 0x8F, 0xF0, 0x07, 0xF8, + 0xFE, 0x00, 0x7F, 0x8F, 0xE0, 0x03, 0xFD, 0xFE, 0x00, 0x3F, 0xDF, 0xC0, + 0x03, 0xFD, 0xFC, 0x00, 0x1F, 0xFF, 0xC0, 0x01, 0xFF, 0xF8, 0x00, 0x1F, + 0xFF, 0x80, 0x00, 0xFF, 0xF8, 0x00, 0x0F, 0xFF, 0x00, 0x00, 0xFF, 0xF0, + 0x00, 0x07, 0xFF, 0x00, 0x00, 0x7F, 0xE0, 0x00, 0x07, 0xFE, 0x00, 0x00, + 0x3F, 0xE0, 0x00, 0x03, 0xFC, 0x00, 0x00, 0x3F, 0xC0, 0x00, 0x07, 0xFE, + 0x00, 0x00, 0x7F, 0xE0, 0x00, 0x07, 0xFE, 0x00, 0x00, 0xFF, 0xF0, 0x00, + 0x0F, 0xFF, 0x00, 0x00, 0xFF, 0xF0, 0x00, 0x1F, 0xFF, 0x80, 0x01, 0xFF, + 0xF8, 0x00, 0x1F, 0xFF, 0x80, 0x03, 0xFF, 0xFC, 0x00, 0x3F, 0xBF, 0xC0, + 0x03, 0xFB, 0xFC, 0x00, 0x7F, 0x9F, 0xE0, 0x07, 0xF9, 0xFE, 0x00, 0x7F, + 0x1F, 0xE0, 0x0F, 0xF0, 0xFF, 0x00, 0xFF, 0x0F, 0xF0, 0x0F, 0xE0, 0xFF, + 0x01, 0xFE, 0x07, 0xF8, 0x1F, 0xE0, 0x7F, 0x81, 0xFC, 0x07, 0xFC, 0x3F, + 0xC0, 0x3F, 0xC3, 0xFC, 0x03, 0xFC, 0x3F, 0xC0, 0x3F, 0xE7, 0xF8, 0x01, + 0xFE, 0x7F, 0x80, 0x1F, 0xE7, 0xF8, 0x01, 0xFF, 0xFF, 0x00, 0x0F, 0xF0, + 0xFF, 0x00, 0x1F, 0xFF, 0xF0, 0x01, 0xFF, 0xFF, 0x80, 0x1F, 0xFF, 0xF8, + 0x01, 0xFE, 0x7F, 0x80, 0x1F, 0xE7, 0xF8, 0x01, 0xFE, 0x7F, 0x80, 0x1F, + 0xE7, 0xF8, 0x01, 0xFE, 0x7F, 0x80, 0x3F, 0xE7, 0xF8, 0x03, 0xFC, 0x3F, + 0xC0, 0x3F, 0xC3, 0xFC, 0x03, 0xFC, 0x3F, 0xC0, 0x3F, 0xC3, 0xFC, 0x03, + 0xFC, 0x3F, 0xC0, 0x3F, 0xC3, 0xFC, 0x03, 0xF8, 0x1F, 0xC0, 0x7F, 0x81, + 0xFE, 0x07, 0xF8, 0x1F, 0xE0, 0x7F, 0x81, 0xFE, 0x07, 0xF8, 0x1F, 0xE0, + 0x7F, 0x81, 0xFE, 0x07, 0xF0, 0x0F, 0xE0, 0x7F, 0x00, 0xFE, 0x07, 0xF0, + 0x0F, 0xE0, 0x7F, 0x00, 0xFF, 0x0F, 0xF0, 0x0F, 0xF0, 0xFF, 0x00, 0xFF, + 0x0F, 0xE0, 0x07, 0xF0, 0xFE, 0x00, 0x7F, 0x0F, 0xE0, 0x07, 0xF0, 0xFE, + 0x00, 0x7F, 0x0F, 0xE0, 0x07, 0xF0, 0xFE, 0x00, 0x7F, 0x8F, 0xC0, 0x03, + 0xF9, 0xFC, 0x00, 0x3F, 0x9F, 0xC0, 0x03, 0xF9, 0xFC, 0x00, 0x3F, 0x9F, + 0xC0, 0x03, 0xF9, 0xFC, 0x00, 0x3F, 0x9F, 0x80, 0x01, 0xF9, 0xF8, 0x00, + 0x1F, 0x9F, 0x80, 0x01, 0xFD, 0xF8, 0x00, 0x1F, 0xDF, 0x80, 0x01, 0xFD, + 0xF8, 0x00, 0x1F, 0xFF, 0x00, 0x00, 0xFF, 0xF0, 0x00, 0x0F, 0xFF, 0x00, + 0x00, 0xFF, 0xF0, 0x00, 0x0F, 0xFF, 0x00, 0x00, 0xFF, 0xF0, 0x00, 0x0F, + 0xFE, 0x00, 0x00, 0x7F, 0xE0, 0x00, 0x07, 0xFE, 0x00, 0x00, 0x7F, 0xE0, + 0x00, 0x07, 0xFE, 0x00, 0x00, 0x7F, 0xE0, 0x00, 0x07, 0xFC, 0x00, 0x00, + 0x7F, 0xC0, 0x00, 0x07, 0xFC, 0x00, 0x3F, 0xFF, 0xC0, 0x03, 0xFF, 0xFC, + 0x00, 0x3F, 0xFF, 0x80, 0x03, 0xFF, 0xF8, 0x00, 0x3F, 0xFF, 0x80, 0x03, + 0xFF, 0xF0, 0x00, 0x3F, 0xFC, 0x00, 0x00, 0x7F, 0xFF, 0xFB, 0xFF, 0xFF, + 0xDF, 0xFF, 0xFE, 0xFF, 0xFF, 0xF7, 0xFF, 0xFF, 0xBF, 0xFF, 0xFD, 0xFF, + 0xFF, 0xE0, 0x01, 0xFF, 0x00, 0x0F, 0xF8, 0x00, 0x7F, 0x80, 0x07, 0xFC, + 0x00, 0x3F, 0xE0, 0x01, 0xFF, 0x00, 0x0F, 0xF0, 0x00, 0xFF, 0x80, 0x07, + 0xFC, 0x00, 0x3F, 0xC0, 0x03, 0xFE, 0x00, 0x1F, 0xF0, 0x00, 0xFF, 0x00, + 0x0F, 0xF8, 0x00, 0x7F, 0xC0, 0x03, 0xFE, 0x00, 0x1F, 0xE0, 0x01, 0xFF, + 0x00, 0x0F, 0xF8, 0x00, 0x7F, 0x80, 0x07, 0xFC, 0x00, 0x3F, 0xE0, 0x01, + 0xFF, 0x00, 0x0F, 0xF0, 0x00, 0xFF, 0x80, 0x07, 0xFC, 0x00, 0x3F, 0xC0, + 0x03, 0xFE, 0x00, 0x1F, 0xF0, 0x00, 0xFF, 0x80, 0x07, 0xF8, 0x00, 0x7F, + 0xC0, 0x03, 0xFE, 0x00, 0x1F, 0xE0, 0x01, 0xFF, 0x00, 0x0F, 0xF8, 0x00, + 0x7F, 0xC0, 0x07, 0xFC, 0x00, 0x3F, 0xE0, 0x01, 0xFF, 0x00, 0x0F, 0xF0, + 0x00, 0xFF, 0x80, 0x07, 0xFC, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xF8, 0x00, 0x0F, 0xF0, 0x03, 0xFF, 0x00, 0xFF, 0xF0, 0x1F, 0xFF, 0x01, + 0xFF, 0xF0, 0x1F, 0xFF, 0x03, 0xFF, 0xF0, 0x3F, 0xF0, 0x03, 0xFE, 0x00, + 0x3F, 0xE0, 0x03, 0xFE, 0x00, 0x3F, 0xC0, 0x03, 0xFC, 0x00, 0x3F, 0xC0, + 0x03, 0xFC, 0x00, 0x3F, 0xC0, 0x03, 0xFC, 0x00, 0x3F, 0xC0, 0x03, 0xFC, + 0x00, 0x3F, 0xC0, 0x03, 0xFC, 0x00, 0x3F, 0xC0, 0x03, 0xFC, 0x00, 0x3F, + 0xC0, 0x03, 0xFC, 0x00, 0x3F, 0xC0, 0x03, 0xFC, 0x00, 0x3F, 0xC0, 0x07, + 0xFC, 0x00, 0x7F, 0xC0, 0x07, 0xFC, 0x00, 0x7F, 0xC0, 0x0F, 0xFC, 0x0F, + 0xFF, 0x80, 0xFF, 0xF8, 0x0F, 0xFF, 0x00, 0xFF, 0xC0, 0x0F, 0xF8, 0x00, + 0xFF, 0xE0, 0x0F, 0xFF, 0x00, 0xFF, 0xF8, 0x0F, 0xFF, 0x80, 0x0F, 0xFC, + 0x00, 0x7F, 0xC0, 0x07, 0xFC, 0x00, 0x7F, 0xC0, 0x03, 0xFC, 0x00, 0x3F, + 0xC0, 0x03, 0xFC, 0x00, 0x3F, 0xC0, 0x03, 0xFC, 0x00, 0x3F, 0xC0, 0x03, + 0xFC, 0x00, 0x3F, 0xC0, 0x03, 0xFC, 0x00, 0x3F, 0xC0, 0x03, 0xFC, 0x00, + 0x3F, 0xC0, 0x03, 0xFC, 0x00, 0x3F, 0xC0, 0x03, 0xFC, 0x00, 0x3F, 0xC0, + 0x03, 0xFC, 0x00, 0x3F, 0xC0, 0x03, 0xFE, 0x00, 0x3F, 0xE0, 0x03, 0xFE, + 0x00, 0x3F, 0xF8, 0x03, 0xFF, 0xF0, 0x1F, 0xFF, 0x01, 0xFF, 0xF0, 0x0F, + 0xFF, 0x00, 0x7F, 0xF0, 0x03, 0xFF, 0x00, 0x07, 0xF0, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0xFF, 0x00, + 0x1F, 0xF8, 0x03, 0xFF, 0x80, 0x7F, 0xF8, 0x0F, 0xFF, 0x81, 0xFF, 0xF0, + 0x3F, 0xFE, 0x00, 0x7F, 0xC0, 0x07, 0xFC, 0x00, 0xFF, 0x80, 0x1F, 0xF0, + 0x03, 0xFE, 0x00, 0x7F, 0xC0, 0x0F, 0xF8, 0x01, 0xFF, 0x00, 0x3F, 0xE0, + 0x07, 0xFC, 0x00, 0xFF, 0x80, 0x1F, 0xF0, 0x03, 0xFE, 0x00, 0x7F, 0xC0, + 0x0F, 0xF8, 0x01, 0xFF, 0x00, 0x3F, 0xE0, 0x07, 0xFC, 0x00, 0xFF, 0x80, + 0x1F, 0xF0, 0x03, 0xFE, 0x00, 0x7F, 0xC0, 0x0F, 0xF8, 0x01, 0xFF, 0x00, + 0x1F, 0xF0, 0x03, 0xFF, 0x00, 0x7F, 0xFC, 0x07, 0xFF, 0x80, 0x7F, 0xF0, + 0x07, 0xFE, 0x00, 0x3F, 0xC0, 0x1F, 0xF8, 0x0F, 0xFF, 0x03, 0xFF, 0xE0, + 0x7F, 0xFC, 0x0F, 0xF8, 0x01, 0xFF, 0x00, 0x7F, 0xC0, 0x0F, 0xF8, 0x01, + 0xFF, 0x00, 0x3F, 0xE0, 0x07, 0xFC, 0x00, 0xFF, 0x80, 0x1F, 0xF0, 0x03, + 0xFE, 0x00, 0x7F, 0xC0, 0x0F, 0xF8, 0x01, 0xFF, 0x00, 0x3F, 0xE0, 0x07, + 0xFC, 0x00, 0xFF, 0x80, 0x1F, 0xF0, 0x03, 0xFE, 0x00, 0x7F, 0xC0, 0x0F, + 0xF8, 0x01, 0xFF, 0x00, 0x3F, 0xE0, 0x07, 0xFC, 0x00, 0xFF, 0x80, 0x3F, + 0xF0, 0x0F, 0xFC, 0x0F, 0xFF, 0x81, 0xFF, 0xF0, 0x3F, 0xFC, 0x07, 0xFF, + 0x80, 0xFF, 0xE0, 0x1F, 0xF0, 0x03, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x18, 0x00, 0x7C, 0x00, 0x07, 0xE0, 0x7F, 0xF0, 0x01, 0xFC, 0x3F, 0xFF, + 0xC0, 0xFF, 0x1F, 0xFF, 0xFE, 0xFF, 0x8F, 0xFF, 0xFF, 0xFF, 0xE3, 0xFF, + 0xFF, 0xFF, 0xF9, 0xFF, 0xFF, 0xFF, 0xFC, 0x7F, 0xFF, 0xFF, 0xFE, 0x3F, + 0xFF, 0xFF, 0xFF, 0x8F, 0xF0, 0x3F, 0xFF, 0xC0, 0xF8, 0x01, 0xFF, 0xE0, + 0x0E, 0x00, 0x0F, 0xF0, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x07, 0xFC, + 0x00, 0x00, 0x3F, 0xFF, 0x00, 0x01, 0xFF, 0xFF, 0x00, 0x07, 0xFF, 0xFF, + 0x00, 0x1F, 0xFF, 0xFF, 0x00, 0x3F, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFE, + 0x01, 0xFF, 0xFF, 0xFE, 0x07, 0xFE, 0x07, 0xFC, 0x0F, 0xF8, 0x0F, 0xF8, + 0x1F, 0xF0, 0x0F, 0xF8, 0x3F, 0xE0, 0x1F, 0xF0, 0xFF, 0x80, 0x3F, 0xE1, + 0xFF, 0x00, 0x7F, 0xC3, 0xFE, 0x00, 0xFF, 0x87, 0xFC, 0x00, 0xFF, 0x0F, + 0xF8, 0x01, 0xFE, 0x1F, 0xF0, 0x03, 0xFC, 0x3F, 0xE0, 0x07, 0xF8, 0x7F, + 0xC0, 0x0F, 0xF0, 0xFF, 0x80, 0x1F, 0xE1, 0xFF, 0x00, 0x3F, 0xC3, 0xFE, + 0x00, 0x7F, 0x87, 0xFC, 0x00, 0xFF, 0x0F, 0xF8, 0x01, 0xFE, 0x1F, 0xF0, + 0x03, 0xFF, 0xFF, 0xFF, 0xC7, 0xFF, 0xFF, 0xFF, 0x80, 0x0F, 0xFF, 0xFF, + 0x00, 0x1F, 0xFF, 0xFE, 0x00, 0x3F, 0xFF, 0xFC, 0x00, 0x07, 0xFC, 0x00, + 0x00, 0x0F, 0xF8, 0x00, 0x00, 0x1F, 0xF0, 0x00, 0x00, 0x3F, 0xE0, 0x00, + 0x07, 0xFF, 0xFF, 0x80, 0x0F, 0xFF, 0xFF, 0x00, 0x1F, 0xFF, 0xFE, 0x00, + 0x3F, 0xFF, 0xFC, 0x00, 0x7F, 0xFF, 0xF8, 0x00, 0x0F, 0xF8, 0x00, 0x00, + 0x1F, 0xF0, 0x03, 0xFC, 0x3F, 0xE0, 0x07, 0xF8, 0x7F, 0xC0, 0x0F, 0xF0, + 0xFF, 0x80, 0x1F, 0xE1, 0xFF, 0x00, 0x3F, 0xC3, 0xFE, 0x00, 0x7F, 0x87, + 0xFC, 0x00, 0xFF, 0x0F, 0xF8, 0x01, 0xFE, 0x1F, 0xF0, 0x03, 0xFC, 0x3F, + 0xE0, 0x07, 0xF8, 0x7F, 0xC0, 0x0F, 0xF0, 0xFF, 0x80, 0x1F, 0xE1, 0xFF, + 0x00, 0x7F, 0xC3, 0xFE, 0x00, 0xFF, 0x87, 0xFC, 0x01, 0xFF, 0x07, 0xF8, + 0x03, 0xFE, 0x0F, 0xF8, 0x07, 0xFC, 0x1F, 0xF0, 0x0F, 0xF0, 0x3F, 0xE0, + 0x3F, 0xE0, 0x3F, 0xE0, 0xFF, 0xC0, 0x7F, 0xFF, 0xFF, 0x80, 0xFF, 0xFF, + 0xFE, 0x00, 0xFF, 0xFF, 0xFC, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0xFF, 0xFF, + 0xC0, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xF8, 0x00, 0x00, 0x1F, 0x80, + 0x00}; const GFXglyph Antonio_SemiBold40pt7bGlyphs[] PROGMEM = { {0, 1, 1, 17, 0, 0}, // 0x20 ' ' @@ -518,7 +1562,7 @@ const GFXglyph Antonio_SemiBold40pt7bGlyphs[] PROGMEM = { {4810, 22, 38, 28, 3, -47}, // 0x3E '>' {4915, 24, 68, 33, 5, -67}, // 0x3F '?' {5119, 48, 71, 58, 5, -67}, // 0x40 '@' - {5545, 31, 69, 37, 2, -67}, // 0x41 'A' + {5545, 31, 67, 35, 2, -66}, // 0x41 'A' {5805, 28, 67, 36, 5, -66}, // 0x42 'B' {6040, 27, 69, 36, 5, -67}, // 0x43 'C' {6273, 28, 67, 37, 5, -66}, // 0x44 'D' @@ -544,10 +1588,10 @@ const GFXglyph Antonio_SemiBold40pt7bGlyphs[] PROGMEM = { {10963, 28, 67, 32, 2, -66}, // 0x58 'X' {11198, 31, 67, 32, 1, -66}, // 0x59 'Y' {11458, 23, 67, 27, 3, -66}, // 0x5A 'Z' - {18021, 31, 69, 37, 2, -67}, // 0x5B '[' --> euro { 18290, 31, 69, 37, 2, -67 } was {11651, 17, 70, 26, 6, -66} - {11800, 24, 67, 30, 3, -66}, // 0x5C '\' - {18557, 30, 68, 36, 3, -67 }, // 0x5D ']' --> pound { 0, 30, 68, 36, 3, -67 } was {12001, 16, 70, 26, 4, -66} - {18812, 31, 67, 32, 1, -66 }, // 0x5E '^' --> yen { 0, 31, 67, 32, 1, -66 } was {12141, 29, 35, 37, 4, -66 + {11651, 17, 70, 26, 6, -66}, // 0x5B '[' + {11800, 24, 67, 30, 3, -66}, // 0x5C '\' + {12001, 16, 70, 26, 4, -66}, // 0x5D ']' + {12141, 29, 35, 37, 4, -66}, // 0x5E '^' {12268, 25, 7, 29, 2, 2}, // 0x5F '_' {12290, 12, 15, 16, 2, -77}, // 0x60 '`' {12313, 27, 59, 36, 4, -57}, // 0x61 'a' @@ -579,35 +1623,10 @@ const GFXglyph Antonio_SemiBold40pt7bGlyphs[] PROGMEM = { {17509, 20, 75, 27, 4, -67}, // 0x7B '{' {17697, 9, 75, 21, 6, -70}, // 0x7C '|' {17782, 19, 75, 27, 4, -67}, // 0x7D '}' - {17961, 34, 14, 43, 4, -44}}; // 0x7E '~' + {17961, 34, 14, 43, 4, -44}, {18021, 31, 69, 37, 2, -67}}; // 0x7E '~' - -//, {18021, 31, 69, 37, 2, -67} - -// const GFXfont Antonio_SemiBold40pt7b PROGMEM = { -// (uint8_t *)Antonio_SemiBold40pt7bBitmaps, -// (GFXglyph *)Antonio_SemiBold40pt7bGlyphs, 0x20, 0x7E, 100}; +const GFXfont Antonio_SemiBold40pt7b PROGMEM = { + (uint8_t *)Antonio_SemiBold40pt7bBitmaps, + (GFXglyph *)Antonio_SemiBold40pt7bGlyphs, 0x20, 0x7E, 101}; // Approx. 18961 bytes - -// // Font metadata structure -// struct FontData { -// const uint8_t* compressedData; -// const GFXglyph* glyphs; -// const size_t compressedSize; -// const size_t originalSize; -// const uint16_t first; -// const uint16_t last; -// const uint8_t yAdvance; -// }; - -// Font properties -static constexpr FontData Antonio_SemiBold40pt7b_Properties = { - Antonio_SemiBold40pt7bBitmaps_Gzip, - Antonio_SemiBold40pt7bGlyphs, - sizeof(Antonio_SemiBold40pt7bBitmaps_Gzip), - 19072, // Original size - 0x20, // First char - 0x7E, // Last char - 100 // yAdvance -}; diff --git a/src/fonts/antonio-semibold90.h b/src/fonts/antonio-semibold90.h index 4f57cb4..b55d5df 100644 --- a/src/fonts/antonio-semibold90.h +++ b/src/fonts/antonio-semibold90.h @@ -1,1023 +1,5035 @@ -#pragma once - #include #include -// #include "fonts.hpp" - -//unsigned int antonio_90_c_len = 6 -const uint8_t Antonio_SemiBold90pt7bBitmaps_Gzip[] = { - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xed, 0x7d, - 0x4b, 0x8e, 0xde, 0x38, 0x97, 0x25, 0x05, 0x15, 0xa0, 0x1e, 0x34, 0xa0, - 0x1d, 0x94, 0x7a, 0x19, 0x35, 0x68, 0xb4, 0x6a, 0x29, 0xbd, 0x84, 0x5a, - 0x40, 0xa3, 0x28, 0xc3, 0x03, 0x0f, 0xbd, 0x04, 0x2f, 0x25, 0x65, 0x78, - 0xe0, 0x61, 0x2c, 0xc1, 0x4a, 0x78, 0xe0, 0x61, 0xca, 0xf0, 0xc0, 0x32, - 0x52, 0x16, 0x5b, 0xbc, 0xe7, 0x1c, 0x92, 0xfa, 0x1e, 0xf1, 0x48, 0xdb, - 0xe9, 0xf0, 0x9f, 0xf1, 0x01, 0x11, 0x94, 0x48, 0xf1, 0xf2, 0x75, 0x79, - 0xdf, 0xa2, 0x5c, 0x08, 0x5f, 0x43, 0xf8, 0x1c, 0xc2, 0xbb, 0x10, 0xfc, - 0xdd, 0x97, 0x4b, 0x08, 0xef, 0x43, 0x78, 0x19, 0xb6, 0xfe, 0x5e, 0x97, - 0xaf, 0x43, 0x68, 0xc2, 0xda, 0x85, 0xd9, 0xdf, 0x7d, 0x39, 0x86, 0xad, - 0x0e, 0x4b, 0x1b, 0xa6, 0x3e, 0x0c, 0xf7, 0xb8, 0xac, 0xc2, 0xdc, 0x84, - 0xb1, 0x0b, 0xce, 0xaf, 0xf7, 0xb9, 0xac, 0xc3, 0xd0, 0x6e, 0xae, 0x5f, - 0x5c, 0x98, 0xee, 0x73, 0xd9, 0xac, 0xae, 0x9b, 0x9d, 0x1f, 0xab, 0xe0, - 0x6e, 0xbf, 0x74, 0xf7, 0xfa, 0x35, 0xf7, 0x9d, 0xdf, 0xb3, 0xcb, 0x31, - 0xf0, 0xf7, 0x5b, 0xd8, 0x42, 0xf8, 0x12, 0xc2, 0x87, 0x10, 0x5e, 0x85, - 0xcd, 0xc7, 0xcb, 0xb7, 0x21, 0x74, 0x61, 0xf5, 0xe1, 0x63, 0xbe, 0xfc, - 0x3d, 0x84, 0x17, 0x61, 0xeb, 0xc2, 0x92, 0x2f, 0xcb, 0x59, 0xee, 0x23, - 0xbc, 0x8b, 0xf3, 0xb9, 0xd6, 0x61, 0x6e, 0xc3, 0xd8, 0x07, 0x97, 0x2e, - 0x37, 0x17, 0x96, 0x3a, 0x4c, 0x6d, 0x18, 0x74, 0xd9, 0x04, 0xd7, 0xad, - 0xce, 0xcf, 0x55, 0x18, 0x75, 0x19, 0x47, 0xb7, 0x83, 0x70, 0x3b, 0x8c, - 0xfd, 0xca, 0x07, 0x57, 0x85, 0x75, 0xbf, 0xd8, 0x01, 0x5b, 0xb6, 0x73, - 0x5d, 0x18, 0x9d, 0xdf, 0xe2, 0x63, 0x7b, 0xc1, 0x0e, 0xd9, 0x66, 0xe3, - 0xae, 0xe7, 0x83, 0x3d, 0xbf, 0x59, 0x36, 0x9e, 0xef, 0xec, 0xf9, 0xfe, - 0x9e, 0xcf, 0xcf, 0x96, 0x6d, 0xcf, 0x3b, 0x7b, 0xbe, 0xba, 0xef, 0xf3, - 0x43, 0xcc, 0xc6, 0xf3, 0x8d, 0x3d, 0xdf, 0xde, 0xf3, 0xf9, 0xd5, 0xb2, - 0xf1, 0x7c, 0x6f, 0xcf, 0xfb, 0x7b, 0x3e, 0x9f, 0x26, 0x63, 0xb3, 0x66, - 0x9d, 0xcd, 0xd2, 0x7d, 0x9e, 0xcf, 0x93, 0x31, 0x5b, 0xb3, 0xce, 0x66, - 0xe9, 0x3e, 0xcf, 0xe7, 0xc9, 0x18, 0xf2, 0xe2, 0x1c, 0x9f, 0xf7, 0x42, - 0xbc, 0x37, 0xba, 0xd8, 0x71, 0x89, 0xbf, 0x59, 0x17, 0x3b, 0x86, 0xf1, - 0xb7, 0xf6, 0xba, 0xfa, 0x3d, 0x15, 0xb6, 0xba, 0x58, 0x6e, 0x05, 0xf6, - 0x97, 0x16, 0xb3, 0xf9, 0xcb, 0x8b, 0xd9, 0xff, 0xd5, 0xc5, 0x7c, 0xd8, - 0xe2, 0x6c, 0x17, 0x17, 0xc7, 0xdf, 0xb5, 0x38, 0xdf, 0x75, 0x66, 0x6f, - 0x03, 0x36, 0x3d, 0x9a, 0x9d, 0xf6, 0x8b, 0xee, 0x9c, 0xf1, 0xda, 0xce, - 0xb9, 0x0f, 0x59, 0x13, 0x19, 0x7c, 0xf8, 0x64, 0x0f, 0xdf, 0x32, 0xd9, - 0x36, 0xb9, 0x93, 0x25, 0xed, 0x6a, 0x49, 0x65, 0x00, 0xf7, 0x47, 0x8c, - 0x92, 0xbb, 0x86, 0x4f, 0x59, 0xb5, 0x1d, 0xea, 0x62, 0x49, 0x1d, 0x7e, - 0x50, 0x55, 0x9b, 0x87, 0xfd, 0x19, 0x1b, 0xc2, 0x9e, 0xc4, 0xec, 0x2a, - 0xa2, 0xa9, 0x4d, 0xa2, 0x65, 0x47, 0x84, 0xdd, 0xe2, 0xe4, 0xda, 0x6d, - 0x1d, 0x70, 0x4b, 0x14, 0x36, 0x6c, 0x5e, 0x51, 0x18, 0xc6, 0x0a, 0x28, - 0x4e, 0xd2, 0x35, 0x20, 0x77, 0xa9, 0x81, 0xef, 0xcc, 0x9d, 0xb1, 0x3b, - 0x76, 0xce, 0x17, 0x96, 0x9d, 0x2b, 0x8f, 0xde, 0x9e, 0xdf, 0x79, 0x63, - 0x88, 0x4c, 0xfa, 0x79, 0xb0, 0x69, 0xdc, 0x59, 0x66, 0x9c, 0xd7, 0xad, - 0x45, 0x53, 0xaf, 0x63, 0x6e, 0x17, 0xf7, 0xce, 0x12, 0x3b, 0xb0, 0x6f, - 0xa6, 0xd8, 0xad, 0x8f, 0xb1, 0x03, 0x8d, 0x09, 0x3a, 0xf1, 0xa1, 0xb7, - 0x31, 0xb7, 0x8b, 0x42, 0x8f, 0xf5, 0xb2, 0x8b, 0x63, 0xf0, 0xe1, 0x53, - 0x1c, 0x52, 0x1b, 0xf9, 0xf5, 0x1c, 0x07, 0x76, 0x83, 0x87, 0xbe, 0x1c, - 0x1f, 0x7a, 0x8f, 0x87, 0x56, 0x3e, 0xf4, 0xf2, 0x14, 0xbe, 0x91, 0x85, - 0x37, 0xe8, 0xc4, 0xe2, 0xd1, 0x89, 0x36, 0x18, 0x8d, 0xfe, 0x3d, 0x18, - 0x06, 0x5b, 0xff, 0x2b, 0xeb, 0xbf, 0xcd, 0xa8, 0x0f, 0x36, 0xed, 0x0d, - 0x26, 0xd6, 0x05, 0x2c, 0x7e, 0x8b, 0xdb, 0x8a, 0xb7, 0x5d, 0x9a, 0x76, - 0xbb, 0xed, 0x51, 0x37, 0x4e, 0x17, 0x41, 0x00, 0x49, 0x6f, 0xbb, 0x6d, - 0x79, 0x1b, 0x1e, 0x72, 0x7b, 0x15, 0xf2, 0xc6, 0xdb, 0xe9, 0x78, 0x3b, - 0xe2, 0x76, 0x3d, 0xde, 0x2e, 0xbc, 0x1d, 0x70, 0x7b, 0xfb, 0xb0, 0x47, - 0xdc, 0x2e, 0x1c, 0xf6, 0x2e, 0x9e, 0xc6, 0x59, 0xf8, 0x18, 0x8c, 0xe2, - 0x6c, 0x5c, 0xd7, 0x0f, 0xb1, 0xf6, 0x8e, 0x0b, 0xb1, 0x76, 0x1b, 0xa5, - 0x2c, 0x9b, 0x77, 0x5b, 0xc1, 0x0e, 0x2b, 0xb8, 0x3f, 0xf4, 0x47, 0x84, - 0xd9, 0x47, 0xe1, 0x6c, 0x8c, 0xed, 0xfc, 0x86, 0xc5, 0xff, 0x8c, 0x75, - 0xdd, 0xb8, 0xae, 0xef, 0xb0, 0xae, 0x7f, 0x62, 0x5d, 0x03, 0xd7, 0xf5, - 0xa4, 0xea, 0x65, 0xf8, 0x37, 0xf1, 0x21, 0x93, 0xee, 0xc6, 0x58, 0xb5, - 0x37, 0xa1, 0x29, 0x2e, 0x7e, 0x5c, 0xed, 0x05, 0x78, 0x19, 0x17, 0x3f, - 0xe6, 0xda, 0xe2, 0xef, 0xa3, 0x8a, 0x8b, 0xdf, 0x47, 0xb9, 0x2e, 0x2c, - 0x7b, 0x32, 0x01, 0xd1, 0x23, 0x76, 0x1b, 0xde, 0x93, 0xdc, 0x73, 0x37, - 0x54, 0xcc, 0xc5, 0x36, 0x18, 0xb1, 0x39, 0x66, 0x6c, 0xa4, 0x0d, 0xdb, - 0x6b, 0x6f, 0xaa, 0x2f, 0x76, 0xdb, 0x82, 0x3d, 0xb8, 0x62, 0x67, 0x06, - 0x2e, 0xe4, 0x90, 0x17, 0xa3, 0xc2, 0xdd, 0x4f, 0x26, 0x25, 0x57, 0xaa, - 0x62, 0xcd, 0x0f, 0x3f, 0x76, 0xfb, 0x34, 0x4f, 0xf4, 0xb1, 0x03, 0xf2, - 0x24, 0x02, 0x64, 0x50, 0x05, 0xc6, 0x93, 0x38, 0x59, 0x77, 0x78, 0xd1, - 0x07, 0xce, 0x47, 0x6c, 0x36, 0x08, 0x08, 0x91, 0xde, 0xca, 0xd1, 0x5c, - 0x4b, 0xda, 0x55, 0x36, 0x82, 0x09, 0x1f, 0x0f, 0x8d, 0x54, 0x21, 0x57, - 0x4e, 0x8d, 0x84, 0xa2, 0xb2, 0x1a, 0xe9, 0x43, 0x6e, 0xb9, 0x4f, 0x03, - 0xce, 0x95, 0xd5, 0x48, 0x43, 0xba, 0x78, 0xd2, 0xc8, 0xc6, 0xdd, 0x53, - 0x36, 0xb2, 0x8b, 0xf6, 0xac, 0x94, 0x1b, 0x59, 0xd2, 0x2c, 0xe6, 0x91, - 0x18, 0x56, 0x9e, 0x8c, 0xc4, 0x68, 0xe5, 0x78, 0xd2, 0x48, 0xc4, 0xed, - 0xf9, 0xd0, 0x88, 0x37, 0xf4, 0x5f, 0x4f, 0xa6, 0xcb, 0x76, 0xc8, 0xa1, - 0x91, 0x06, 0x9b, 0x68, 0x2a, 0x1b, 0xb1, 0x67, 0x5a, 0x40, 0x2f, 0xd6, - 0x64, 0x44, 0xeb, 0x87, 0x35, 0x99, 0x23, 0xf4, 0xa1, 0x6c, 0xa4, 0x05, - 0x2a, 0x4f, 0x65, 0x23, 0x35, 0x78, 0xcb, 0x52, 0x36, 0x62, 0xf5, 0x08, - 0x30, 0x35, 0x62, 0xf5, 0x00, 0xb0, 0xd6, 0x3a, 0x94, 0x00, 0xd5, 0x48, - 0x09, 0x50, 0x8d, 0x94, 0x00, 0x53, 0x23, 0x05, 0xc0, 0xd4, 0x48, 0x01, - 0xb0, 0x52, 0x23, 0x25, 0x40, 0x35, 0x52, 0x02, 0x4c, 0x8d, 0x14, 0x00, - 0x53, 0x23, 0x05, 0xc0, 0xd4, 0x48, 0x01, 0x30, 0x35, 0x52, 0x02, 0x4c, - 0x8d, 0x14, 0x00, 0x53, 0x23, 0x05, 0xc0, 0xd4, 0x48, 0x01, 0x30, 0x35, - 0x52, 0x00, 0xcc, 0x8d, 0x14, 0x00, 0x53, 0x23, 0x05, 0xc0, 0xd4, 0x48, - 0x01, 0x30, 0x35, 0x52, 0x00, 0xcc, 0x8d, 0x64, 0x80, 0xb9, 0x91, 0x02, - 0x60, 0x6a, 0xa4, 0x00, 0x88, 0x46, 0xfe, 0xfb, 0x00, 0xd0, 0x1a, 0x69, - 0x41, 0xf7, 0x04, 0xd0, 0x1a, 0xe9, 0x20, 0x5c, 0x08, 0xa0, 0x35, 0xd2, - 0x81, 0x6c, 0x26, 0x80, 0xa0, 0xfc, 0xf1, 0xc1, 0x0c, 0xb0, 0x07, 0xf1, - 0xde, 0x33, 0x32, 0xc0, 0x88, 0xe2, 0xb6, 0x11, 0xe7, 0x0c, 0xb0, 0x01, - 0xe3, 0x31, 0x71, 0x44, 0x00, 0x2b, 0xf0, 0xa6, 0x60, 0xaa, 0xbf, 0x00, - 0xc6, 0x46, 0x40, 0xbf, 0x33, 0xc0, 0xde, 0x44, 0x95, 0x58, 0x39, 0x03, - 0xec, 0x4c, 0xe4, 0x8b, 0xbf, 0x37, 0x09, 0x60, 0x03, 0x9e, 0x11, 0x4c, - 0x1f, 0x20, 0xc0, 0x2a, 0xd1, 0xfa, 0x2d, 0x03, 0x84, 0x08, 0x11, 0x7f, - 0x2f, 0x13, 0x40, 0x34, 0x12, 0xa5, 0xa5, 0xf7, 0x09, 0x20, 0x1a, 0x59, - 0xf7, 0xb2, 0x35, 0x01, 0x6c, 0x4c, 0xc5, 0x32, 0xa0, 0x09, 0x20, 0x1b, - 0x89, 0x37, 0x37, 0x09, 0x20, 0xee, 0xa3, 0x24, 0xf3, 0x29, 0x01, 0xec, - 0x8d, 0x0d, 0x9b, 0xb0, 0x93, 0x00, 0x76, 0x26, 0xd7, 0x18, 0x73, 0xfd, - 0x4d, 0x00, 0xd5, 0xc8, 0xfe, 0xf0, 0x1f, 0x02, 0xc8, 0xe9, 0x8a, 0x90, - 0xfe, 0x4c, 0x00, 0xc1, 0xc8, 0x8d, 0x2a, 0x04, 0x11, 0x87, 0xde, 0x1a, - 0x35, 0xaa, 0xf0, 0x4a, 0xc4, 0x01, 0x6b, 0xb2, 0xc6, 0xc2, 0x0f, 0x48, - 0x26, 0x6b, 0x84, 0x00, 0xbf, 0x52, 0xa4, 0xc3, 0xc2, 0x47, 0x80, 0x55, - 0x64, 0xe6, 0x24, 0x5f, 0x89, 0xb6, 0xf9, 0x9d, 0xdf, 0x93, 0x7c, 0xf5, - 0x2a, 0xec, 0x76, 0x91, 0x80, 0x75, 0x12, 0x6d, 0x6b, 0x30, 0x5f, 0xbd, - 0x35, 0xba, 0x24, 0x80, 0x3d, 0x24, 0x38, 0x61, 0x97, 0x01, 0xbc, 0x31, - 0xa5, 0x62, 0xd3, 0xb0, 0x0d, 0x60, 0x14, 0x14, 0x6a, 0x00, 0x18, 0x13, - 0x40, 0x6f, 0xf2, 0xed, 0xa4, 0x7a, 0x56, 0x20, 0x16, 0xd0, 0x68, 0xb1, - 0xf6, 0x82, 0xb7, 0x64, 0x01, 0x15, 0x16, 0xcb, 0x00, 0xce, 0xe2, 0x29, - 0x58, 0x2c, 0x00, 0x14, 0x4f, 0xb1, 0x7d, 0x42, 0x80, 0x0d, 0x99, 0x94, - 0xc1, 0x52, 0x4b, 0x65, 0x23, 0x02, 0xd8, 0x43, 0x5e, 0xa8, 0x80, 0x62, - 0x00, 0xd8, 0x90, 0xf7, 0x18, 0x8a, 0x11, 0xa0, 0x63, 0xc3, 0xd6, 0x88, - 0x00, 0x76, 0x90, 0x2e, 0xec, 0x56, 0x00, 0x6b, 0x74, 0xa6, 0xc1, 0xc6, - 0x00, 0x40, 0x63, 0x7b, 0x23, 0x77, 0xbc, 0x00, 0xd6, 0xe0, 0xa2, 0x69, - 0xa7, 0x59, 0x41, 0x9f, 0xf6, 0x49, 0x02, 0xb8, 0x17, 0xac, 0x8e, 0x57, - 0x09, 0x20, 0x7e, 0x20, 0x2b, 0x02, 0x88, 0x5f, 0x45, 0xfa, 0x40, 0x80, - 0x99, 0x12, 0x15, 0x00, 0x49, 0x89, 0xc6, 0x33, 0x80, 0xad, 0x95, 0x1e, - 0x01, 0xa2, 0xf4, 0x08, 0xb0, 0x22, 0x55, 0x3b, 0x00, 0x94, 0x2a, 0x54, - 0x02, 0x04, 0xed, 0x3a, 0x02, 0x44, 0x23, 0x47, 0x80, 0xa8, 0x71, 0x04, - 0x58, 0x91, 0x16, 0x1f, 0x00, 0x4a, 0x8c, 0x2b, 0x01, 0xf6, 0x54, 0x87, - 0x4b, 0x80, 0x2d, 0x25, 0xf4, 0x12, 0x60, 0x43, 0x05, 0xb4, 0x04, 0x58, - 0x49, 0x66, 0x2f, 0x01, 0x8a, 0x25, 0x95, 0x00, 0x7b, 0x4a, 0xf1, 0x25, - 0x40, 0x34, 0x72, 0x04, 0xd8, 0x48, 0xea, 0x2f, 0x00, 0x56, 0x62, 0xa4, - 0x25, 0x40, 0x31, 0xd2, 0x12, 0x60, 0x2f, 0xe9, 0x14, 0x02, 0x4b, 0xd1, - 0x08, 0x89, 0x43, 0x38, 0x34, 0xd2, 0x15, 0x22, 0x83, 0x1a, 0x69, 0x44, - 0x15, 0x8a, 0x46, 0x4a, 0x19, 0x24, 0x15, 0x7a, 0x93, 0x96, 0xb7, 0x43, - 0x23, 0x24, 0x45, 0x43, 0xd9, 0x08, 0x49, 0xd1, 0x54, 0x36, 0x42, 0x4a, - 0xb2, 0x94, 0x8d, 0x90, 0x4a, 0x24, 0x69, 0x66, 0x02, 0xc0, 0x2c, 0x76, - 0xa9, 0x91, 0x28, 0x62, 0x55, 0x59, 0x82, 0x44, 0x05, 0x6f, 0x7a, 0xc1, - 0xb1, 0x91, 0x7d, 0x7b, 0x0d, 0xe1, 0xa4, 0x91, 0xba, 0x94, 0x2a, 0xd5, - 0x2b, 0xb0, 0x80, 0x43, 0x23, 0xd2, 0x16, 0x0e, 0x8d, 0x80, 0x2a, 0x1c, - 0x1b, 0x21, 0x93, 0x3a, 0x34, 0x22, 0x25, 0xfd, 0xd0, 0x48, 0x73, 0xa1, - 0x11, 0x57, 0x88, 0xb3, 0x69, 0xe8, 0x5d, 0x6e, 0xb8, 0x10, 0x89, 0x52, - 0xc3, 0xa9, 0x91, 0x52, 0x5a, 0x4f, 0x0b, 0xd6, 0x64, 0x21, 0x3c, 0xef, - 0x2c, 0x9f, 0xf2, 0xf2, 0xaf, 0xbe, 0xa0, 0x12, 0x24, 0x55, 0xa2, 0x2e, - 0xe4, 0x8d, 0xa2, 0x07, 0x03, 0x3b, 0xaf, 0x2b, 0xaf, 0x8e, 0x56, 0xa9, - 0xcb, 0x4d, 0xba, 0xca, 0xc3, 0xf0, 0x1a, 0x64, 0x95, 0x86, 0x5b, 0xa7, - 0xab, 0x36, 0x4d, 0x4b, 0x9f, 0xae, 0xbc, 0xd6, 0x28, 0x56, 0xf0, 0x34, - 0x13, 0x45, 0x5b, 0x3c, 0x36, 0x79, 0x20, 0xe1, 0xea, 0x92, 0x1d, 0xaa, - 0x0f, 0x32, 0x0a, 0x79, 0xd3, 0x64, 0x27, 0x27, 0x96, 0x3b, 0x5a, 0xd5, - 0x01, 0x56, 0xaa, 0x06, 0x0c, 0xca, 0x71, 0x77, 0x90, 0xd2, 0x2d, 0xb4, - 0x2c, 0xf5, 0xc6, 0xb5, 0x16, 0x27, 0xd4, 0x9e, 0x09, 0xa4, 0x21, 0xe5, - 0x1c, 0x00, 0xb8, 0x06, 0xc9, 0x1e, 0x9d, 0x18, 0xf3, 0x40, 0x70, 0x06, - 0x18, 0xe0, 0xb6, 0x33, 0x70, 0x0d, 0xc1, 0x9d, 0xf5, 0xae, 0x4a, 0xbd, - 0xab, 0xc1, 0xc3, 0x39, 0x44, 0x2c, 0x7d, 0x9b, 0x4c, 0x5b, 0x6d, 0x1a, - 0x6c, 0x67, 0xea, 0xc9, 0xc4, 0x61, 0xf7, 0x94, 0x56, 0x67, 0xa7, 0xb9, - 0x9b, 0x2a, 0x49, 0xb5, 0x63, 0x43, 0x99, 0x37, 0x8c, 0x89, 0xd4, 0x40, - 0x3e, 0xb3, 0xc6, 0xbc, 0x2c, 0x09, 0x95, 0x8c, 0x08, 0x1b, 0xb5, 0x89, - 0xbd, 0xb1, 0xa4, 0x21, 0xac, 0x9d, 0x14, 0x92, 0x85, 0xb4, 0xc7, 0x0c, - 0x35, 0x44, 0x80, 0x4f, 0xc4, 0x0f, 0x0f, 0xf9, 0xc4, 0x01, 0xa5, 0xb5, - 0x4f, 0x4b, 0xf4, 0x18, 0x84, 0x45, 0x5b, 0xc2, 0x27, 0x54, 0xc8, 0x28, - 0xdb, 0x26, 0xc4, 0x97, 0xe1, 0xc4, 0xd0, 0x28, 0xed, 0xd6, 0x4c, 0x81, - 0x0a, 0x85, 0x15, 0x15, 0x5c, 0x28, 0xa8, 0x6f, 0xa2, 0xcd, 0x42, 0xfb, - 0x3a, 0x55, 0x68, 0xd3, 0xee, 0xe9, 0x8b, 0x0a, 0x19, 0xc7, 0x79, 0xd5, - 0x84, 0x62, 0x37, 0x26, 0x2d, 0x2e, 0xeb, 0x78, 0x49, 0x57, 0xb5, 0xab, - 0xff, 0x81, 0x0e, 0xef, 0x4d, 0xfc, 0x07, 0xd0, 0x78, 0xbf, 0xfa, 0x2f, - 0xcc, 0xc4, 0x4e, 0xc5, 0x67, 0x8d, 0xbf, 0xa1, 0x38, 0xbc, 0x93, 0xbe, - 0xc9, 0x91, 0xf7, 0xf7, 0xb4, 0xe8, 0x99, 0xfa, 0x1e, 0x0d, 0x32, 0x71, - 0xbd, 0x47, 0x5a, 0x45, 0x9a, 0xb8, 0x82, 0x21, 0xae, 0x7c, 0x17, 0x06, - 0x5b, 0x89, 0x25, 0x2e, 0xda, 0xbe, 0xec, 0xf1, 0xca, 0x84, 0x8a, 0xa9, - 0x37, 0x91, 0x21, 0x2e, 0xac, 0x8f, 0x72, 0x76, 0x14, 0x3e, 0x22, 0x0e, - 0x74, 0x76, 0xe3, 0xcc, 0xdc, 0x37, 0xf5, 0xf6, 0xf4, 0x68, 0xcf, 0x4c, - 0x66, 0x33, 0xdb, 0x2a, 0x18, 0x0f, 0x5f, 0x46, 0xd7, 0x57, 0x80, 0x61, - 0x6e, 0x6e, 0xad, 0xc9, 0xcd, 0x04, 0x93, 0x85, 0xa2, 0x29, 0x44, 0xb5, - 0x38, 0x2f, 0xc0, 0x5d, 0xd8, 0x53, 0x06, 0xeb, 0xfe, 0x5c, 0x43, 0x00, - 0x34, 0x44, 0xdb, 0x70, 0x35, 0x74, 0x90, 0xf3, 0xf6, 0xfb, 0x1e, 0xec, - 0xca, 0xac, 0x8d, 0x13, 0x4d, 0x62, 0x14, 0x59, 0xac, 0x17, 0x98, 0xc8, - 0xc1, 0xaa, 0x9a, 0x09, 0xce, 0x76, 0x51, 0x1d, 0x6c, 0xb8, 0x0b, 0x2d, - 0x5e, 0x3d, 0x64, 0xa3, 0x1d, 0x80, 0xa7, 0xca, 0x32, 0x02, 0x48, 0x0b, - 0xd9, 0x7d, 0x88, 0x2b, 0x44, 0xa1, 0xdb, 0xf6, 0x43, 0x43, 0x21, 0x69, - 0x26, 0x07, 0x84, 0xa8, 0xb8, 0x10, 0x07, 0x0c, 0x5c, 0x0b, 0x93, 0xe7, - 0x64, 0x8b, 0x3b, 0x82, 0x6d, 0xf8, 0xc4, 0x54, 0x02, 0xae, 0x06, 0xf4, - 0xa9, 0xa6, 0x41, 0x6b, 0xb3, 0x4d, 0x09, 0x6c, 0x6c, 0xb1, 0x51, 0xad, - 0x9f, 0x81, 0xc6, 0xdb, 0x0e, 0xd6, 0x54, 0xeb, 0xb1, 0x99, 0xa6, 0x6c, - 0xa9, 0xa2, 0x04, 0x1b, 0x87, 0x6d, 0x04, 0x8d, 0x13, 0x80, 0xdf, 0x54, - 0xe9, 0x4a, 0x36, 0xdc, 0x74, 0xf5, 0x11, 0x52, 0x6f, 0x30, 0x2b, 0x2c, - 0xaf, 0x9e, 0x53, 0xe0, 0x33, 0xbd, 0x04, 0x58, 0xb4, 0x34, 0xe8, 0x94, - 0x11, 0x46, 0xea, 0x36, 0x03, 0xf9, 0xa5, 0x75, 0x68, 0x25, 0x7a, 0x42, - 0x9c, 0x97, 0x1c, 0x8e, 0xed, 0xc1, 0xb5, 0xe1, 0xa6, 0x70, 0xcd, 0x94, - 0x36, 0x51, 0x34, 0xe1, 0x99, 0x6e, 0x10, 0x95, 0x86, 0x4f, 0x11, 0x1b, - 0x6e, 0xa2, 0x69, 0xae, 0xdf, 0xe5, 0xe9, 0x7d, 0xff, 0xb7, 0xe1, 0xf7, - 0x28, 0x30, 0xbf, 0xd8, 0x25, 0xe9, 0xad, 0xdb, 0x35, 0xae, 0xd9, 0xef, - 0xaa, 0xd8, 0xeb, 0x88, 0x8f, 0x75, 0x98, 0xfc, 0x4e, 0x34, 0x9e, 0xed, - 0x22, 0xf1, 0xd6, 0xec, 0x7c, 0x77, 0xee, 0xf6, 0xae, 0x8e, 0xfd, 0xde, - 0x4b, 0xb7, 0x63, 0xe3, 0x8e, 0x65, 0x83, 0x9f, 0xdb, 0xb5, 0xda, 0x31, - 0x6a, 0xde, 0xb9, 0xcc, 0x4e, 0x90, 0x76, 0x3c, 0xda, 0xb1, 0xbf, 0xd9, - 0x71, 0x74, 0xe8, 0xa6, 0x7a, 0x47, 0x92, 0xa1, 0x85, 0xa0, 0x62, 0xc6, - 0xfe, 0xda, 0xf0, 0xc1, 0x66, 0xd2, 0x6c, 0x9c, 0xc1, 0x70, 0x3c, 0x1a, - 0xfc, 0xec, 0x2f, 0x8e, 0xbb, 0xe5, 0x5f, 0x97, 0xff, 0xa2, 0x38, 0x3e, - 0xf4, 0x86, 0x7b, 0x6b, 0xfa, 0xf3, 0xb6, 0x14, 0xa7, 0x7f, 0xf3, 0xd9, - 0x5f, 0x78, 0xfa, 0xfb, 0x25, 0xff, 0x2e, 0xad, 0xe5, 0xa5, 0x35, 0x07, - 0xb7, 0x14, 0x5e, 0x6c, 0x86, 0x5a, 0x3b, 0xce, 0x4c, 0xc2, 0x1f, 0xe1, - 0x53, 0xc3, 0xbf, 0x9a, 0x38, 0x17, 0x71, 0xcf, 0x70, 0xb0, 0x27, 0x4e, - 0x26, 0x46, 0x0d, 0x46, 0x2b, 0x2b, 0x20, 0xfa, 0x13, 0x69, 0xee, 0xe6, - 0x58, 0x6d, 0x08, 0x46, 0x76, 0xc3, 0xc4, 0xbf, 0x99, 0x7f, 0x0b, 0xf6, - 0xaf, 0x3d, 0x6c, 0xce, 0x98, 0xd4, 0xa9, 0xee, 0xe4, 0xaf, 0x4d, 0x7f, - 0xe1, 0xe9, 0xef, 0x5f, 0xfa, 0x0f, 0xeb, 0x7c, 0xba, 0xfe, 0x22, 0x66, - 0x1e, 0xb8, 0x52, 0x1b, 0xa3, 0x00, 0xfe, 0xf0, 0x4f, 0x38, 0x35, 0x11, - 0xd7, 0x06, 0xfc, 0x6d, 0xc4, 0xc5, 0x05, 0xb8, 0xb9, 0x25, 0xff, 0x80, - 0x97, 0x4f, 0x61, 0xbb, 0x5f, 0xda, 0x5f, 0x48, 0x87, 0x4a, 0xe9, 0x18, - 0xd3, 0x7a, 0xac, 0x77, 0xd6, 0xba, 0xcb, 0xa7, 0xd3, 0x2e, 0xe2, 0xec, - 0x69, 0x1b, 0xc9, 0xfa, 0x9e, 0xf6, 0x73, 0x8c, 0x2f, 0x8a, 0x31, 0x33, - 0xad, 0xc5, 0xce, 0x44, 0x3e, 0x31, 0x46, 0x5e, 0xb0, 0xb3, 0x90, 0x9d, - 0x27, 0x98, 0xed, 0x65, 0xee, 0x56, 0x73, 0x16, 0xae, 0xdd, 0x7e, 0xb3, - 0xa7, 0x5b, 0xb7, 0x82, 0x5b, 0x76, 0x71, 0xa0, 0xfb, 0xe5, 0xbb, 0x9d, - 0x21, 0xad, 0x2d, 0xf9, 0x27, 0x3d, 0x9b, 0x71, 0xb3, 0xc5, 0x1f, 0x95, - 0x86, 0x25, 0x39, 0x4b, 0xb3, 0xa8, 0xe9, 0xb3, 0xcb, 0x6f, 0xa1, 0x44, - 0x37, 0x95, 0xa9, 0xf2, 0x7d, 0xd6, 0x34, 0xa0, 0x22, 0x00, 0x4e, 0x47, - 0xb8, 0xd6, 0x17, 0x99, 0x27, 0xa3, 0xb0, 0x62, 0xbf, 0x48, 0x33, 0x62, - 0xbf, 0xe2, 0xfc, 0xbf, 0x5a, 0x42, 0xee, 0x37, 0xc7, 0x11, 0xa2, 0x88, - 0xb6, 0x8b, 0x6b, 0x31, 0x16, 0xc9, 0xc6, 0xa9, 0x71, 0xb7, 0x3b, 0xb3, - 0xdb, 0x99, 0xe0, 0xb2, 0xcf, 0x47, 0x9c, 0x97, 0x45, 0xf3, 0x54, 0x2f, - 0x31, 0xed, 0xe6, 0x9a, 0xf3, 0x57, 0x4d, 0x98, 0xd7, 0x6a, 0x88, 0x69, - 0x35, 0x6a, 0xbe, 0x2f, 0xac, 0xc7, 0x7d, 0xd7, 0x31, 0xa5, 0x72, 0x62, - 0x0c, 0xc6, 0xf1, 0x57, 0x4c, 0x8a, 0xcd, 0x49, 0x6f, 0x45, 0x50, 0x5a, - 0x5c, 0x4b, 0xe5, 0x8d, 0x5e, 0x86, 0xf9, 0xbb, 0x57, 0xe2, 0x9a, 0xfe, - 0x98, 0xdf, 0xf8, 0x73, 0xc6, 0x74, 0xb1, 0xd2, 0xb7, 0x8c, 0x63, 0xaa, - 0xa3, 0x70, 0xbd, 0x4b, 0xd5, 0xc0, 0x17, 0x17, 0x10, 0x89, 0x36, 0xc4, - 0x0d, 0x85, 0xd8, 0xbd, 0x3d, 0x63, 0x8a, 0xe1, 0x7b, 0x3b, 0x0d, 0xb1, - 0x0c, 0xbf, 0x73, 0xa1, 0x5d, 0xba, 0xdc, 0x75, 0x88, 0x98, 0xd1, 0x45, - 0xec, 0x8a, 0xfe, 0xc3, 0x98, 0x31, 0xec, 0x92, 0x57, 0xbb, 0x7e, 0x53, - 0x7f, 0xd2, 0xfc, 0xde, 0x7b, 0x00, 0x98, 0x21, 0xba, 0xa5, 0x17, 0x4c, - 0x14, 0x2d, 0x52, 0x56, 0x96, 0x3c, 0xaa, 0x87, 0x07, 0x69, 0x9f, 0xe2, - 0xf3, 0xc7, 0x07, 0x07, 0xe7, 0x64, 0x14, 0x6a, 0x4e, 0x1e, 0x3c, 0x02, - 0x1e, 0xae, 0x03, 0x9e, 0xaf, 0x03, 0xde, 0x6e, 0x01, 0x3c, 0x66, 0xc0, - 0xf5, 0x2d, 0x80, 0x4f, 0x87, 0x56, 0x00, 0x3e, 0x1d, 0x5a, 0x01, 0xf8, - 0x74, 0x68, 0x3f, 0x6d, 0xce, 0xfe, 0xe2, 0xd0, 0x1e, 0x3e, 0x67, 0xcb, - 0x2d, 0x80, 0xdd, 0xf5, 0x39, 0x9b, 0xae, 0xcf, 0xd9, 0x7a, 0xcb, 0x9c, - 0x0d, 0x8f, 0x70, 0xce, 0xfe, 0x22, 0x3a, 0x3c, 0x86, 0x39, 0xfb, 0x96, - 0x2d, 0x54, 0x34, 0x4b, 0xeb, 0x96, 0x51, 0x0a, 0x63, 0xaf, 0x64, 0xc6, - 0x73, 0x32, 0x1c, 0x76, 0x31, 0x59, 0x64, 0x40, 0x55, 0xac, 0x80, 0xc7, - 0x6d, 0x87, 0x5b, 0xd9, 0x75, 0x49, 0x74, 0x90, 0xbb, 0x36, 0x07, 0x62, - 0xb5, 0x20, 0x37, 0x0a, 0xf7, 0x3b, 0x03, 0x8e, 0x42, 0x53, 0x94, 0xab, - 0x62, 0xf0, 0x60, 0x84, 0xfd, 0x06, 0x56, 0x81, 0x25, 0x36, 0xd5, 0x46, - 0x8d, 0x60, 0x63, 0xac, 0x4a, 0x34, 0xd4, 0x6d, 0x8c, 0x41, 0xba, 0x81, - 0x9d, 0xe3, 0x0b, 0x18, 0x4c, 0x8c, 0x0e, 0x8f, 0x0f, 0xfd, 0x11, 0xcc, - 0x34, 0xf0, 0x35, 0x98, 0xdd, 0x30, 0xfc, 0x06, 0x6b, 0x60, 0xa0, 0xe9, - 0x20, 0xe6, 0x5a, 0xa7, 0xd7, 0x14, 0x38, 0xd1, 0x70, 0x80, 0xe8, 0xb3, - 0x4c, 0xa5, 0x8a, 0x3d, 0xf1, 0x98, 0x85, 0xa7, 0xaa, 0x4f, 0x55, 0x7f, - 0x4c, 0x55, 0xda, 0xea, 0x2e, 0xe1, 0xf0, 0x4a, 0x1c, 0x7e, 0x15, 0xce, - 0x82, 0xf9, 0x0e, 0xa1, 0x5a, 0x66, 0x0b, 0xec, 0xcd, 0xbd, 0x8a, 0x60, - 0xbe, 0xfe, 0x10, 0xaa, 0x55, 0x31, 0x54, 0x8b, 0x71, 0x86, 0x9d, 0x69, - 0xd3, 0xf1, 0x72, 0xb2, 0xee, 0xa4, 0x9d, 0x79, 0xb2, 0x5f, 0x15, 0xaa, - 0xd5, 0x23, 0x17, 0x9b, 0x7a, 0xc1, 0xad, 0xdc, 0xf7, 0x0c, 0x01, 0xa0, - 0x2d, 0x55, 0xb3, 0x40, 0x97, 0xc2, 0x90, 0xec, 0xaf, 0x8e, 0x49, 0x1d, - 0x02, 0x83, 0x71, 0x48, 0x78, 0xfa, 0xe4, 0x21, 0xed, 0x20, 0xe8, 0xcf, - 0xa4, 0x51, 0x46, 0xd8, 0x2c, 0xfe, 0xb1, 0xe5, 0x84, 0xd9, 0xf6, 0xb5, - 0xb8, 0x06, 0xb3, 0xd7, 0xce, 0x50, 0x1a, 0x7a, 0x06, 0x5c, 0x82, 0xd8, - 0x58, 0x97, 0x5f, 0x84, 0x87, 0xfd, 0xbe, 0x5a, 0xd7, 0x6d, 0x70, 0x71, - 0x30, 0x4b, 0xaf, 0x39, 0x18, 0xe3, 0x32, 0xc5, 0x91, 0xcd, 0x70, 0xd0, - 0x20, 0x36, 0x89, 0xc4, 0x70, 0x71, 0xa6, 0x0a, 0x9a, 0x5e, 0x88, 0x3e, - 0x36, 0xb4, 0x53, 0x3e, 0x3d, 0xf8, 0xf4, 0xe0, 0x83, 0x1e, 0xac, 0xa4, - 0xc6, 0xd0, 0x7b, 0x14, 0xe0, 0xb7, 0x0f, 0x52, 0x57, 0x86, 0xe4, 0xc7, - 0xe1, 0x26, 0x23, 0xd9, 0x08, 0x28, 0xc4, 0xf6, 0xc4, 0x46, 0x5c, 0x90, - 0xac, 0xf2, 0xdf, 0x21, 0x19, 0x3a, 0x3c, 0x83, 0x64, 0x86, 0xae, 0x17, - 0xb9, 0xee, 0x4e, 0x00, 0xb6, 0x06, 0x88, 0x1e, 0xfb, 0xb8, 0xff, 0x3d, - 0x83, 0x3e, 0xff, 0x3b, 0x20, 0xce, 0xb1, 0x55, 0x23, 0x26, 0x66, 0xc1, - 0x87, 0x49, 0x3f, 0xd0, 0x9a, 0xfd, 0x12, 0x04, 0xe7, 0x06, 0x5d, 0xf9, - 0x00, 0x03, 0x00, 0xc3, 0x49, 0x19, 0x3f, 0x6a, 0x04, 0xac, 0x41, 0x04, - 0x6a, 0x8d, 0x68, 0xd5, 0x8a, 0xe1, 0xa9, 0x8c, 0x47, 0xf5, 0x88, 0x5d, - 0xed, 0x11, 0xac, 0xda, 0x81, 0xa6, 0x90, 0x3c, 0x92, 0x94, 0x92, 0x76, - 0x8a, 0xce, 0x72, 0xf0, 0x1e, 0x84, 0xa6, 0xc7, 0x1c, 0x3c, 0xbc, 0xa2, - 0x35, 0x3c, 0xa0, 0xe1, 0x51, 0xf2, 0x42, 0x1b, 0xdd, 0x2c, 0xb3, 0x08, - 0x31, 0xa5, 0x07, 0x23, 0xc0, 0x1b, 0x86, 0x1a, 0xe0, 0xc3, 0x70, 0x5c, - 0x48, 0xf8, 0x36, 0x1c, 0x9c, 0x1d, 0x8e, 0x6b, 0x6a, 0x94, 0x1b, 0xe2, - 0x14, 0x65, 0x34, 0x4a, 0x6c, 0x4a, 0x28, 0xef, 0x8d, 0x87, 0x64, 0x82, - 0xc8, 0xc6, 0x64, 0x2e, 0x9a, 0x48, 0xb6, 0x11, 0x26, 0x6b, 0x91, 0xd0, - 0x23, 0xdc, 0x27, 0xf3, 0xca, 0x79, 0xd2, 0x26, 0xd7, 0xee, 0x80, 0xe6, - 0xc7, 0x9c, 0xd4, 0x89, 0x2c, 0x17, 0xd4, 0xb9, 0x3a, 0x24, 0x6a, 0x3e, - 0x25, 0x65, 0xf3, 0xfe, 0xd0, 0xfc, 0xc5, 0x5e, 0xdc, 0xbf, 0xf9, 0xb3, - 0x76, 0xaf, 0x8f, 0x3e, 0xcd, 0xf3, 0x56, 0x24, 0xed, 0xa1, 0xc1, 0x8b, - 0xf3, 0x5c, 0x5d, 0x5c, 0x3c, 0x7f, 0xcb, 0xe2, 0x5d, 0x5c, 0x35, 0x05, - 0x3c, 0x04, 0x09, 0xf2, 0x25, 0x0e, 0xa4, 0xfa, 0xf6, 0x23, 0x33, 0x7a, - 0x83, 0xe4, 0x3d, 0x92, 0x8f, 0x48, 0x16, 0x24, 0x34, 0xb1, 0x6d, 0xd8, - 0xab, 0x0c, 0x9f, 0x8a, 0x51, 0xf8, 0xf1, 0xf7, 0xf6, 0x1e, 0x15, 0x5d, - 0x8a, 0x11, 0xa8, 0x82, 0xe6, 0x47, 0xde, 0x79, 0xcb, 0xc7, 0x76, 0x40, - 0x97, 0x46, 0xca, 0xec, 0xbc, 0xe5, 0xbe, 0x08, 0x33, 0x3b, 0x9c, 0x8c, - 0x79, 0x90, 0x09, 0x48, 0x4f, 0xc4, 0xfd, 0xa3, 0x3f, 0xc7, 0x6a, 0x51, - 0x36, 0x20, 0x29, 0x31, 0x33, 0x67, 0x05, 0x41, 0x22, 0x3e, 0x39, 0xf7, - 0x30, 0x92, 0x3f, 0x8f, 0x13, 0xd4, 0x47, 0x51, 0xc3, 0xb6, 0xcf, 0xcc, - 0xbd, 0xf5, 0x02, 0x1b, 0xd7, 0xc8, 0x09, 0x24, 0x96, 0x11, 0x64, 0xc5, - 0x44, 0xa1, 0x95, 0x92, 0xd1, 0x07, 0xf6, 0xb1, 0x87, 0xdc, 0xf4, 0x85, - 0x5d, 0xbf, 0x01, 0x69, 0x35, 0x21, 0x48, 0x32, 0x91, 0x44, 0x24, 0xee, - 0x62, 0x09, 0x50, 0x92, 0xa7, 0xfa, 0x62, 0xdc, 0x1b, 0xc7, 0x9d, 0x15, - 0x9a, 0x9a, 0xd3, 0x90, 0x2b, 0x4f, 0xc5, 0xc2, 0x6b, 0x55, 0xb5, 0xe4, - 0x44, 0x0b, 0xad, 0x79, 0x9d, 0xc2, 0x65, 0x56, 0x57, 0xe0, 0xd7, 0x95, - 0xa7, 0xba, 0xf4, 0xd4, 0x25, 0x58, 0x27, 0x2d, 0x2a, 0x26, 0x84, 0xa0, - 0xeb, 0x84, 0x6c, 0x88, 0x67, 0xb0, 0xdb, 0x0a, 0x2b, 0x69, 0x43, 0x22, - 0xd3, 0x08, 0x2e, 0x79, 0xc2, 0xe3, 0x16, 0x64, 0xf0, 0x81, 0xd5, 0x6d, - 0x32, 0x76, 0x70, 0xa3, 0x59, 0x0b, 0x6d, 0x38, 0x18, 0x69, 0x15, 0x0b, - 0xd0, 0x85, 0x24, 0xba, 0x31, 0x0c, 0x22, 0x21, 0x76, 0xc9, 0xae, 0xb4, - 0xeb, 0xb5, 0xa7, 0xea, 0xb3, 0xc1, 0xdd, 0x31, 0x7f, 0xb7, 0x4d, 0x6b, - 0x77, 0x84, 0xdd, 0x1c, 0xe7, 0xf1, 0xfa, 0x52, 0x71, 0x11, 0x30, 0x02, - 0x8f, 0x11, 0x48, 0x04, 0xef, 0x80, 0x0d, 0x62, 0x07, 0x92, 0xd7, 0x7b, - 0x60, 0x83, 0x98, 0xc5, 0x77, 0xaa, 0xfc, 0x99, 0x95, 0x5f, 0xa1, 0xf2, - 0xca, 0xca, 0x1f, 0x88, 0x87, 0x3d, 0xf0, 0xf0, 0x0b, 0x55, 0x84, 0x1b, - 0x68, 0x0c, 0xc0, 0x6d, 0x8a, 0xf2, 0x0d, 0x62, 0x0e, 0xe2, 0x3c, 0x92, - 0x8b, 0xbe, 0x01, 0xc3, 0xd3, 0xae, 0x9a, 0x28, 0x0b, 0xd7, 0xf0, 0x59, - 0x2f, 0x1d, 0xf8, 0x7d, 0xdc, 0x92, 0x2f, 0xe0, 0xa4, 0xb0, 0x3e, 0x5b, - 0xcf, 0xb3, 0x4e, 0xce, 0x6c, 0x0c, 0x28, 0x29, 0xf0, 0x43, 0xc5, 0x5d, - 0x8f, 0x7d, 0x3d, 0x60, 0x60, 0xa2, 0x11, 0x59, 0x8d, 0x69, 0x51, 0x4a, - 0xd7, 0x7a, 0xc2, 0x3b, 0x21, 0x9a, 0x88, 0x76, 0x7c, 0x45, 0xd9, 0xb9, - 0x8c, 0xb5, 0xf4, 0xf6, 0x63, 0x8d, 0x16, 0xae, 0x59, 0x50, 0xc1, 0xc4, - 0x82, 0x55, 0x05, 0x43, 0x89, 0x6e, 0x95, 0xc2, 0x41, 0xfa, 0x84, 0x32, - 0x69, 0xb9, 0xb5, 0xfc, 0x69, 0xdd, 0xb5, 0xcd, 0x84, 0xa1, 0x09, 0x7d, - 0x36, 0x15, 0x8c, 0x2c, 0x58, 0x58, 0x10, 0x54, 0x30, 0xb1, 0x60, 0x55, - 0xc1, 0xe0, 0x8a, 0x20, 0x93, 0x3e, 0x24, 0xb6, 0x20, 0x16, 0x20, 0xe6, - 0x91, 0x18, 0x85, 0xa6, 0x20, 0x6d, 0x36, 0xf2, 0xa3, 0xdf, 0xc8, 0xd0, - 0x3e, 0x93, 0x5b, 0x6e, 0xe2, 0x85, 0xef, 0xc8, 0x5a, 0x3f, 0x01, 0x44, - 0xbf, 0xaf, 0xff, 0x64, 0x05, 0x37, 0x00, 0x61, 0x41, 0x08, 0x71, 0x36, - 0x37, 0xd8, 0x6d, 0x9a, 0x9d, 0x2b, 0x60, 0x5f, 0x2f, 0x00, 0xd1, 0x6d, - 0xb0, 0xeb, 0x34, 0x11, 0x37, 0x50, 0x00, 0x10, 0x1d, 0x70, 0x67, 0x2f, - 0x78, 0x0d, 0x10, 0x51, 0xbb, 0x01, 0x65, 0x80, 0x01, 0xa9, 0x89, 0xe8, - 0x33, 0x5a, 0x41, 0xc7, 0x5d, 0x5f, 0x93, 0x84, 0x4c, 0x00, 0x11, 0xdd, - 0x24, 0x88, 0x19, 0x85, 0x41, 0xa9, 0xb6, 0x28, 0x17, 0x2b, 0x00, 0x88, - 0x2e, 0xc0, 0xe0, 0x54, 0x47, 0xf9, 0xd2, 0xb8, 0xcd, 0x0a, 0x10, 0x9d, - 0x45, 0xb8, 0x58, 0x01, 0xa3, 0x3f, 0x56, 0xc5, 0x88, 0x0c, 0x06, 0xa2, - 0x8e, 0x6f, 0xc8, 0x5b, 0x80, 0xc8, 0x0a, 0x10, 0x1d, 0x23, 0x56, 0x6a, - 0x46, 0xb3, 0x44, 0x8b, 0xbd, 0x87, 0x5e, 0x38, 0x30, 0x1e, 0x65, 0x06, - 0x08, 0xcf, 0x88, 0x96, 0x2e, 0x85, 0xac, 0x30, 0x9c, 0xc5, 0x6f, 0xd2, - 0x1f, 0xc7, 0x1a, 0x7b, 0x6f, 0x06, 0x08, 0xbf, 0x49, 0xa7, 0x1c, 0x19, - 0x50, 0xc2, 0x78, 0x16, 0x6f, 0x71, 0x36, 0x70, 0x12, 0x00, 0xc7, 0xf9, - 0xc2, 0x89, 0xa7, 0x73, 0xb9, 0x65, 0x80, 0x0a, 0x5e, 0x8e, 0x44, 0x6c, - 0x59, 0x05, 0x7d, 0x74, 0x34, 0x10, 0x78, 0xbf, 0x77, 0x83, 0x37, 0x07, - 0x62, 0xe8, 0xe4, 0x10, 0xe8, 0xb1, 0x64, 0xff, 0xb4, 0x0f, 0x08, 0x37, - 0x43, 0xac, 0xf5, 0x0a, 0x10, 0x3e, 0xc0, 0x18, 0xd7, 0x9a, 0xd4, 0xca, - 0x77, 0x76, 0xa1, 0x56, 0x0f, 0x06, 0xa2, 0x85, 0x05, 0x00, 0x05, 0xde, - 0xd8, 0xe9, 0x60, 0x20, 0x5a, 0x70, 0xc9, 0xa1, 0x0a, 0x8c, 0x20, 0xe9, - 0x8d, 0x58, 0xc4, 0x51, 0x1a, 0xf1, 0x18, 0x2b, 0x30, 0x35, 0x2a, 0xec, - 0x3f, 0xfd, 0x37, 0xb8, 0x64, 0xe4, 0xcc, 0xc1, 0x2e, 0x8a, 0x8b, 0xa5, - 0xad, 0x32, 0x19, 0x26, 0x1d, 0xcd, 0x9b, 0xb2, 0x65, 0xd2, 0x28, 0xf0, - 0x8b, 0x80, 0xf0, 0x36, 0xe0, 0xf9, 0xa7, 0x25, 0x53, 0xd1, 0xb3, 0x5f, - 0x29, 0xf9, 0xbf, 0x96, 0x74, 0xd8, 0x2b, 0xc1, 0x14, 0xd0, 0xf7, 0xe0, - 0x4d, 0x1f, 0x60, 0xe5, 0xf9, 0x23, 0x52, 0x5f, 0x0c, 0xf3, 0x98, 0x0c, - 0x48, 0xc6, 0x43, 0x32, 0x1d, 0x92, 0x8b, 0x93, 0x15, 0x0d, 0x3e, 0x6f, - 0x2c, 0x89, 0x8c, 0x71, 0xf1, 0xd6, 0xca, 0xc2, 0xf8, 0x14, 0x6f, 0x84, - 0xc0, 0xde, 0x8a, 0x2d, 0x13, 0xdb, 0xc1, 0x97, 0x92, 0x2d, 0x25, 0x63, - 0x91, 0xb4, 0x48, 0x9c, 0x1b, 0xb3, 0x3e, 0x78, 0xff, 0x24, 0x3c, 0xc2, - 0x24, 0xd8, 0x30, 0xef, 0x9f, 0x6c, 0x7f, 0x57, 0xb2, 0x9e, 0x26, 0x33, - 0x44, 0xae, 0x63, 0x92, 0xd6, 0xd6, 0x17, 0xeb, 0x1e, 0x55, 0x15, 0x33, - 0xfc, 0x05, 0xbe, 0x45, 0x92, 0x92, 0x0e, 0x48, 0xc4, 0x84, 0x4a, 0x12, - 0x13, 0xe8, 0x48, 0x8c, 0x0a, 0x4c, 0x7a, 0x55, 0xfc, 0x4f, 0x3b, 0x03, - 0x0d, 0xa2, 0xd4, 0xbd, 0xa6, 0x1c, 0xb8, 0xed, 0x25, 0xa2, 0x38, 0x24, - 0x12, 0x58, 0xc0, 0xef, 0x21, 0x6c, 0xc4, 0x9a, 0x23, 0x67, 0x9c, 0xa2, - 0x7e, 0x56, 0x66, 0x1a, 0xb6, 0x82, 0x6e, 0x51, 0x8c, 0x73, 0x12, 0xdf, - 0xd0, 0xf7, 0x01, 0xfd, 0xd3, 0x0b, 0xe9, 0xec, 0x75, 0x12, 0x01, 0x79, - 0x4b, 0xbd, 0x2d, 0x0e, 0x34, 0xb6, 0x55, 0x61, 0xe3, 0xcd, 0x51, 0xed, - 0x68, 0x20, 0x55, 0x46, 0x7a, 0xd8, 0x83, 0x95, 0x3d, 0xa7, 0x75, 0x99, - 0xaa, 0xdb, 0x0b, 0xd8, 0xa9, 0x4d, 0x32, 0xbd, 0xf3, 0xf6, 0x6d, 0x32, - 0x6a, 0x97, 0xef, 0xa2, 0xaf, 0x34, 0x6c, 0xdd, 0x80, 0xd5, 0xda, 0xe2, - 0xb9, 0xa4, 0xe6, 0x7d, 0xfb, 0x6d, 0xd6, 0x2d, 0xbe, 0xf3, 0xed, 0xff, - 0xb6, 0xdb, 0x8a, 0x26, 0x21, 0x6f, 0x2c, 0x39, 0xba, 0xaf, 0x66, 0x18, - 0xc3, 0xe2, 0x74, 0x6f, 0xc5, 0x74, 0x97, 0xaa, 0x72, 0x80, 0xf5, 0xcd, - 0x16, 0x05, 0xc9, 0xc6, 0xdb, 0x09, 0x89, 0x0e, 0xd8, 0xd0, 0x09, 0x1a, - 0x34, 0x06, 0x2c, 0xf9, 0xd6, 0x96, 0x2d, 0x40, 0x4f, 0xbf, 0xc1, 0x1a, - 0xad, 0x34, 0x76, 0x71, 0x62, 0x37, 0xce, 0xc6, 0x1f, 0x54, 0x98, 0xcb, - 0xdb, 0x86, 0xb7, 0xfe, 0xf4, 0x36, 0x6b, 0x35, 0xf7, 0xbd, 0xad, 0x79, - 0xdb, 0xff, 0xe2, 0xb7, 0xd2, 0xe2, 0xf2, 0x2d, 0xb5, 0x37, 0x9a, 0x2f, - 0xaf, 0xde, 0x9a, 0x37, 0x12, 0x3c, 0x6a, 0x48, 0xb7, 0xb4, 0x6a, 0xb4, - 0xe9, 0xf8, 0x84, 0xf7, 0xd8, 0xa5, 0x31, 0xac, 0x2a, 0x36, 0xf0, 0x1a, - 0x86, 0xd5, 0xe8, 0x84, 0x89, 0xdb, 0x72, 0xbf, 0x8d, 0x87, 0x2e, 0x2d, - 0x97, 0x71, 0x44, 0x02, 0x05, 0xb6, 0xf3, 0x26, 0x87, 0x0c, 0x36, 0xfb, - 0xca, 0xbd, 0x4f, 0x3b, 0x70, 0xf2, 0xcc, 0xe2, 0xa9, 0xec, 0x9e, 0x6a, - 0x90, 0x9b, 0xd4, 0x7a, 0x7f, 0x34, 0xe8, 0xe1, 0x28, 0xa5, 0xf0, 0x18, - 0x7e, 0x52, 0xf3, 0x16, 0x6e, 0x35, 0xa9, 0x7f, 0xb6, 0x03, 0x65, 0x19, - 0x20, 0x3b, 0x4a, 0x16, 0x82, 0x2b, 0x8f, 0x37, 0x57, 0x1e, 0xf7, 0x67, - 0x8f, 0x8f, 0x97, 0x1f, 0x5f, 0x4f, 0x1e, 0x9f, 0x2e, 0x3f, 0xbe, 0x7d, - 0x9f, 0xc7, 0x1f, 0xd8, 0x99, 0xc3, 0xe3, 0xe7, 0x33, 0x23, 0x45, 0xfa, - 0x7b, 0x4c, 0x64, 0x9d, 0x3b, 0x75, 0xf2, 0xb8, 0x3a, 0x75, 0xed, 0xf1, - 0xe1, 0xf2, 0xe3, 0x87, 0x56, 0x4e, 0x1f, 0x57, 0xa7, 0xfa, 0xab, 0xcb, - 0x35, 0xf1, 0xf1, 0x91, 0x8f, 0x5f, 0x6c, 0x25, 0x5b, 0x08, 0x2e, 0xb6, - 0xd2, 0x9d, 0xb5, 0xa2, 0x6a, 0x77, 0xb4, 0xa2, 0x6a, 0xd7, 0x5a, 0xb9, - 0x58, 0xed, 0xbc, 0x95, 0x8b, 0xd5, 0x64, 0x21, 0xb9, 0xde, 0xb9, 0x43, - 0xb5, 0x26, 0x57, 0xbb, 0x63, 0x4c, 0x0b, 0x5b, 0x39, 0xad, 0x76, 0x9f, - 0xd6, 0x6e, 0xa9, 0xc6, 0xb1, 0x85, 0xfb, 0x8c, 0xad, 0xb9, 0x5a, 0x4d, - 0x6c, 0x55, 0x72, 0xd0, 0xb5, 0x56, 0xad, 0x5a, 0x7e, 0x15, 0x2f, 0x24, - 0x97, 0x99, 0x4c, 0x94, 0xf2, 0x99, 0xc9, 0x0a, 0x37, 0x27, 0xdb, 0x15, - 0x88, 0x29, 0x6f, 0x75, 0x66, 0x8f, 0xde, 0x01, 0x19, 0x44, 0x5b, 0x3d, - 0xb2, 0x65, 0x35, 0xeb, 0x91, 0x4d, 0x73, 0x77, 0x24, 0xc8, 0x91, 0x5c, - 0x8f, 0xf0, 0xb0, 0x99, 0xeb, 0xcc, 0x99, 0xe0, 0xb8, 0x92, 0xa8, 0x47, - 0x1a, 0xbf, 0x75, 0x10, 0xff, 0xcc, 0xdc, 0x5d, 0x9b, 0xdc, 0x13, 0x75, - 0x79, 0x1d, 0xd4, 0xf3, 0x91, 0x86, 0xb4, 0x57, 0x30, 0xf6, 0x49, 0xfe, - 0x21, 0xfb, 0x30, 0x37, 0xbe, 0xeb, 0xe1, 0xd5, 0xaf, 0x68, 0xc8, 0x6e, - 0x69, 0xc8, 0xe6, 0x91, 0x2e, 0x35, 0x5d, 0x68, 0x99, 0xc7, 0x8b, 0x33, - 0xfd, 0x06, 0x09, 0xf1, 0x2b, 0xcd, 0xdd, 0x64, 0xfd, 0x62, 0x58, 0x77, - 0x56, 0x3e, 0xb4, 0x4c, 0x81, 0x6c, 0xa3, 0xfd, 0x5d, 0xdd, 0x7e, 0xc9, - 0x6e, 0x97, 0x36, 0x4a, 0x13, 0x7c, 0xcc, 0x3e, 0x61, 0xda, 0xa7, 0xe4, - 0x44, 0xb3, 0x51, 0xae, 0x14, 0x8f, 0x4c, 0x4e, 0xa7, 0x31, 0x64, 0xa6, - 0x07, 0xd1, 0xec, 0x43, 0xbd, 0xbd, 0x42, 0x1e, 0x2d, 0x8f, 0x23, 0x5e, - 0xae, 0x8a, 0xf2, 0xaa, 0x9d, 0x03, 0x12, 0xff, 0xe8, 0x49, 0x08, 0xe0, - 0x97, 0xc5, 0x0a, 0xd2, 0xbd, 0x17, 0xf2, 0x3a, 0xf7, 0xb8, 0x95, 0xa0, - 0xdc, 0xc5, 0x94, 0xfc, 0x4f, 0x1e, 0x42, 0xc5, 0x0e, 0x9f, 0x78, 0x3b, - 0xd4, 0x84, 0x79, 0x3b, 0xa2, 0x25, 0xb2, 0x81, 0xc4, 0x6f, 0xdb, 0xc1, - 0xdb, 0x4b, 0x56, 0xd6, 0x99, 0x0e, 0x4f, 0x3a, 0x74, 0x26, 0x62, 0x83, - 0x11, 0x09, 0x0f, 0xae, 0x5b, 0x53, 0x36, 0xee, 0x60, 0xdc, 0x31, 0x17, - 0xaa, 0x59, 0x6f, 0xcd, 0xad, 0x21, 0x29, 0xf8, 0x0d, 0x23, 0x19, 0x7a, - 0x4c, 0x98, 0x8e, 0x62, 0xd2, 0x6c, 0x73, 0x9d, 0xaf, 0xb8, 0x35, 0x02, - 0x97, 0xaa, 0xd4, 0x04, 0xee, 0x74, 0x6b, 0x84, 0x47, 0x53, 0x39, 0xa3, - 0xe7, 0x01, 0xc3, 0x28, 0x31, 0x7d, 0xa2, 0x5e, 0xf3, 0x8a, 0x7e, 0x20, - 0x4e, 0x98, 0x04, 0x29, 0xc6, 0x80, 0xcd, 0x94, 0x71, 0x9e, 0x43, 0x4f, - 0x89, 0x12, 0x54, 0xdc, 0xbc, 0x51, 0x8e, 0x7e, 0x16, 0x0c, 0xc3, 0xac, - 0x37, 0x1d, 0x52, 0xee, 0x67, 0x1d, 0xc2, 0x35, 0x60, 0x9d, 0x93, 0x46, - 0x24, 0x11, 0x0a, 0xbb, 0x7f, 0x12, 0x92, 0xa0, 0x38, 0xc7, 0xe7, 0x48, - 0xe4, 0xed, 0x30, 0xb0, 0x64, 0xd3, 0xf5, 0xc9, 0x2a, 0x0c, 0xb2, 0xd7, - 0x82, 0x4b, 0x1d, 0xa3, 0xe9, 0x9a, 0x40, 0xf3, 0xa8, 0x81, 0xaa, 0xca, - 0xb9, 0xe2, 0x1c, 0xcd, 0x92, 0xd9, 0x84, 0x9c, 0xe8, 0x1d, 0x91, 0x92, - 0xa6, 0x7a, 0x91, 0xa6, 0x11, 0x23, 0x93, 0x5d, 0x5f, 0xa2, 0x22, 0xc7, - 0x5b, 0xe3, 0x72, 0xc2, 0x18, 0x6d, 0xce, 0x9a, 0x1c, 0x4d, 0xe7, 0x81, - 0xf8, 0xdc, 0x94, 0x97, 0x4e, 0x7e, 0xb2, 0xed, 0x4f, 0x3a, 0x34, 0x27, - 0x75, 0xa1, 0x03, 0x45, 0x91, 0xf5, 0x9f, 0x7d, 0x97, 0x97, 0xa3, 0x5c, - 0xee, 0x2c, 0x5b, 0xfb, 0x90, 0x89, 0xf0, 0x90, 0x86, 0xdd, 0x17, 0x13, - 0x3a, 0xa2, 0xea, 0xf2, 0x78, 0xab, 0x2e, 0x89, 0xa8, 0x08, 0x03, 0xca, - 0xb1, 0x0e, 0x07, 0x4d, 0x41, 0x4a, 0xd6, 0x88, 0x08, 0x87, 0x25, 0xc5, - 0x34, 0x48, 0x61, 0x38, 0x9b, 0xcb, 0x57, 0x41, 0x51, 0x5d, 0x23, 0x96, - 0x61, 0x91, 0x32, 0x57, 0x9b, 0xaa, 0x67, 0xb8, 0xcc, 0x75, 0xa5, 0xff, - 0x57, 0xc7, 0x27, 0xbe, 0x40, 0x42, 0x2b, 0x96, 0x94, 0x47, 0xea, 0x92, - 0x52, 0x1b, 0xc8, 0xb4, 0x68, 0xba, 0x90, 0xcb, 0x76, 0xc0, 0xad, 0x31, - 0xbe, 0x3f, 0x80, 0x1e, 0x3c, 0x87, 0x6c, 0x01, 0xa5, 0x9f, 0x25, 0xe2, - 0x91, 0xeb, 0x76, 0xc9, 0xff, 0x38, 0x80, 0x57, 0xcf, 0x40, 0x6e, 0xb9, - 0x52, 0x46, 0xec, 0x80, 0x85, 0x9c, 0xfa, 0x5e, 0x55, 0xbd, 0x08, 0xc0, - 0x7a, 0x01, 0xe5, 0x3e, 0x24, 0xc6, 0x38, 0x26, 0xd7, 0x99, 0x87, 0x73, - 0xe4, 0x9b, 0xaa, 0xae, 0x44, 0xf4, 0x97, 0xd8, 0xe1, 0x1f, 0x93, 0x82, - 0xb6, 0x90, 0x2e, 0x93, 0x4c, 0x67, 0xaa, 0xcd, 0xa3, 0xf7, 0x38, 0x35, - 0x8d, 0x05, 0xab, 0x0e, 0xa2, 0xf8, 0x60, 0x00, 0x03, 0x4c, 0x26, 0xc6, - 0x35, 0x30, 0xb3, 0x27, 0x07, 0xfe, 0x4d, 0xd8, 0xdb, 0x8b, 0xfc, 0xea, - 0x64, 0x3c, 0xda, 0xea, 0x56, 0x67, 0x3b, 0x72, 0xa9, 0xe9, 0xe0, 0x6e, - 0x14, 0xd1, 0x00, 0x45, 0xb1, 0xe9, 0xf6, 0x87, 0xf0, 0x09, 0x57, 0xcb, - 0xc9, 0xfb, 0xd7, 0x7e, 0xa0, 0x5d, 0x7f, 0xef, 0xaf, 0xff, 0xcb, 0xbd, - 0xb5, 0xad, 0xf1, 0xa7, 0x09, 0x46, 0xbf, 0xc5, 0xfd, 0xf6, 0xc0, 0xcb, - 0xe9, 0x27, 0x0c, 0xd6, 0x7e, 0xed, 0x37, 0x8c, 0x38, 0x04, 0x1e, 0x8a, - 0x3c, 0xf4, 0xbb, 0x28, 0xba, 0xe8, 0x58, 0x69, 0x65, 0xd9, 0xe1, 0xc8, - 0xc8, 0xb2, 0x43, 0xa7, 0x87, 0x8e, 0x59, 0xf6, 0x62, 0x53, 0xca, 0xf2, - 0xbb, 0x1c, 0x83, 0x2c, 0x9c, 0x31, 0x6d, 0x59, 0xec, 0xdd, 0x60, 0xff, - 0x47, 0xfb, 0x3f, 0xc5, 0x7f, 0x15, 0x54, 0x20, 0xc8, 0xe1, 0xd8, 0xc5, - 0x74, 0x7c, 0x62, 0x30, 0x83, 0xfd, 0x8f, 0x15, 0x3a, 0x9b, 0xd3, 0x8e, - 0x26, 0xcb, 0xc5, 0x89, 0x1d, 0x42, 0xa8, 0xf7, 0x86, 0xb8, 0x41, 0x41, - 0x6c, 0x23, 0x7d, 0xac, 0x70, 0xa8, 0x22, 0xd4, 0xa0, 0x0e, 0x62, 0xc1, - 0xf0, 0x3b, 0xcf, 0xfc, 0xdf, 0x05, 0xb1, 0xe4, 0x91, 0xb6, 0xd0, 0x3e, - 0xc8, 0xbd, 0x22, 0x97, 0x73, 0x90, 0x11, 0x14, 0x4c, 0x7b, 0x95, 0x4f, - 0xb7, 0x93, 0x9b, 0x7a, 0x96, 0xfa, 0x80, 0xcd, 0x42, 0x7a, 0x25, 0xf6, - 0x3d, 0x58, 0x6f, 0x9d, 0xf5, 0x1f, 0x23, 0x9a, 0x9c, 0xf8, 0x37, 0xa8, - 0x16, 0x95, 0xc0, 0xc0, 0x21, 0x05, 0x27, 0x3f, 0x73, 0x6a, 0x21, 0xc8, - 0xe9, 0x5b, 0x85, 0xc4, 0x1d, 0xb5, 0x55, 0xeb, 0x32, 0xab, 0x2b, 0xb3, - 0xd0, 0x65, 0x64, 0x35, 0x41, 0x7a, 0xca, 0x26, 0xab, 0x2f, 0x20, 0xd2, - 0x12, 0x8c, 0x21, 0x35, 0xd6, 0x07, 0xba, 0xc1, 0x7b, 0xd1, 0x83, 0x21, - 0x8d, 0xc9, 0x5b, 0x47, 0x71, 0xb4, 0x04, 0xc3, 0x81, 0x3c, 0x02, 0x9a, - 0x6c, 0xe1, 0x78, 0x7a, 0x21, 0xb5, 0x44, 0x5b, 0xe9, 0xc6, 0x56, 0xda, - 0xc1, 0xd7, 0xf5, 0x1f, 0xf6, 0xff, 0xdf, 0xbe, 0x0d, 0x4b, 0x2f, 0xff, - 0xee, 0xb1, 0x3b, 0x1e, 0xfc, 0xfb, 0x11, 0xfd, 0xb4, 0xa9, 0x71, 0xff, - 0x59, 0x4c, 0xc7, 0xbf, 0xdb, 0xff, 0x16, 0xb3, 0x05, 0x55, 0x96, 0x6c, - 0xcf, 0xb2, 0x18, 0x3e, 0x06, 0x77, 0x3e, 0x5c, 0xf4, 0x96, 0x25, 0xa7, - 0x3b, 0xfc, 0xe5, 0xc4, 0xbb, 0x15, 0xbd, 0x76, 0x86, 0x0e, 0x53, 0x81, - 0xa8, 0x09, 0x5b, 0xb0, 0x05, 0x6e, 0x47, 0x8d, 0xe1, 0x7a, 0x56, 0xc4, - 0xbf, 0xb5, 0xcc, 0xd2, 0x66, 0x63, 0x00, 0x04, 0xe4, 0xd1, 0x4a, 0x22, - 0xec, 0xe6, 0x64, 0x67, 0xa9, 0xb4, 0x1d, 0x46, 0xa7, 0x2d, 0x50, 0x17, - 0x68, 0xa4, 0x93, 0x5e, 0x72, 0x85, 0x8e, 0x6e, 0xfc, 0x58, 0xa1, 0x97, - 0xf0, 0x34, 0xcb, 0xa6, 0x68, 0xdd, 0xa8, 0x8a, 0xff, 0x40, 0xf9, 0x26, - 0xfd, 0x9f, 0xe9, 0x0d, 0xc1, 0x7f, 0x0c, 0xb4, 0x0f, 0xc7, 0x0d, 0xae, - 0x6d, 0xde, 0x07, 0x6e, 0x1d, 0xe8, 0x19, 0x9b, 0xf6, 0x41, 0xad, 0xdd, - 0xb0, 0x38, 0x99, 0x1b, 0x3c, 0x49, 0x10, 0xe2, 0x1b, 0x26, 0x27, 0x02, - 0xd5, 0x90, 0x59, 0x0e, 0x36, 0x54, 0x5b, 0x64, 0x9a, 0x1d, 0xec, 0xff, - 0xff, 0x29, 0x56, 0xfa, 0x7f, 0xda, 0xff, 0x7f, 0x13, 0x92, 0x75, 0x9c, - 0x05, 0x82, 0x67, 0xbb, 0x12, 0x0b, 0x17, 0xc9, 0x97, 0x14, 0x84, 0x63, - 0x87, 0xc5, 0xd8, 0x91, 0x47, 0x99, 0x9d, 0xa2, 0x17, 0x3d, 0x00, 0x53, - 0x6f, 0xc9, 0x33, 0xfb, 0xbf, 0x41, 0x3a, 0x88, 0x5a, 0x4c, 0x30, 0xdd, - 0x26, 0xbe, 0x5c, 0xfb, 0x06, 0x56, 0x86, 0x38, 0xd7, 0x34, 0x1b, 0x40, - 0x4f, 0xac, 0x60, 0x25, 0x68, 0x20, 0x3a, 0x32, 0x06, 0x8e, 0xef, 0xbf, - 0x20, 0x5e, 0xae, 0x56, 0x51, 0xf0, 0xd2, 0x97, 0xa9, 0xe2, 0x4a, 0x2b, - 0xa3, 0xae, 0xf6, 0x68, 0x8a, 0xe8, 0xf0, 0xe2, 0x3c, 0x8f, 0x09, 0xc5, - 0xc8, 0x4a, 0x48, 0x7e, 0x1b, 0x06, 0xc0, 0x40, 0xe8, 0xf4, 0x17, 0x8a, - 0x68, 0xb8, 0xba, 0x04, 0x09, 0x46, 0x29, 0xda, 0xa2, 0xda, 0xf2, 0xf1, - 0x2a, 0x69, 0x68, 0xa3, 0x13, 0x4d, 0xe5, 0xfe, 0x68, 0x01, 0xdd, 0xdb, - 0xe3, 0x4d, 0x52, 0xfb, 0xe6, 0xe4, 0xc2, 0xeb, 0x93, 0x55, 0x9d, 0xda, - 0x9c, 0x69, 0xf5, 0xda, 0x80, 0x13, 0x28, 0x54, 0x0a, 0xc5, 0x6b, 0x53, - 0x25, 0xe0, 0x2b, 0x29, 0xc3, 0x52, 0x8e, 0x77, 0xc2, 0x00, 0x06, 0x1b, - 0x00, 0xfd, 0xbf, 0xcb, 0x8f, 0x2f, 0xfa, 0x09, 0xbf, 0x56, 0xa1, 0x51, - 0x8c, 0xf0, 0x1d, 0x5d, 0x0a, 0xa9, 0x78, 0x94, 0x45, 0xec, 0xf4, 0x54, - 0x8e, 0x80, 0x16, 0xc8, 0xf8, 0x6b, 0xb0, 0xd4, 0xfc, 0x19, 0x9e, 0x0f, - 0xf9, 0xb9, 0x7c, 0x27, 0x0d, 0x0c, 0x77, 0xdd, 0xe1, 0x0e, 0x37, 0xa1, - 0xac, 0xa5, 0x3b, 0x8f, 0x9b, 0x2d, 0xb7, 0x15, 0x8a, 0x20, 0x39, 0xfb, - 0x2d, 0x05, 0xf8, 0x20, 0x2d, 0x0b, 0x14, 0x03, 0xbd, 0xf6, 0xe2, 0x03, - 0x1c, 0x23, 0x22, 0xba, 0xb8, 0xa9, 0xca, 0xcd, 0x42, 0xc8, 0x9d, 0x38, - 0xd8, 0x88, 0xbb, 0x2c, 0xd6, 0x71, 0x52, 0x64, 0x1c, 0x07, 0xd7, 0x68, - 0x72, 0x5f, 0x87, 0xec, 0x42, 0x70, 0xd4, 0x5d, 0x0c, 0x86, 0xab, 0xb1, - 0x5f, 0x36, 0xcd, 0xd9, 0x52, 0x4c, 0xaf, 0x82, 0x99, 0x34, 0x33, 0x83, - 0x4b, 0x07, 0xb0, 0x99, 0x7c, 0xd6, 0xa7, 0xb9, 0x87, 0xe9, 0x22, 0x4d, - 0xe8, 0x52, 0x3c, 0x88, 0xf3, 0xec, 0xb5, 0x60, 0x08, 0xe7, 0x1a, 0x32, - 0x90, 0x74, 0x36, 0xaf, 0xc9, 0x45, 0xe9, 0xd0, 0x37, 0x03, 0x02, 0x49, - 0xb0, 0xb3, 0x91, 0x4c, 0x3a, 0x74, 0xd1, 0xc4, 0xbb, 0xa1, 0xe5, 0x9e, - 0x8f, 0xcc, 0x36, 0xba, 0xde, 0x46, 0xf1, 0xa4, 0x10, 0x83, 0xd6, 0xa4, - 0x9b, 0x99, 0x90, 0xbd, 0xc8, 0x7a, 0x60, 0x02, 0xfa, 0xa4, 0x48, 0x00, - 0x8b, 0x83, 0x1b, 0x64, 0x3c, 0x8b, 0x12, 0xfc, 0x9a, 0xbc, 0x73, 0x51, - 0x87, 0x94, 0x89, 0x7a, 0xb0, 0xd0, 0xba, 0xe4, 0xda, 0x6f, 0xe3, 0x07, - 0x52, 0xf8, 0x60, 0xd4, 0x36, 0x6b, 0x30, 0x9c, 0x21, 0x42, 0xf6, 0x76, - 0x0e, 0x18, 0x4e, 0x56, 0xdd, 0x15, 0xd2, 0xd9, 0x9b, 0xe5, 0x71, 0x8c, - 0x3d, 0x8c, 0xa1, 0x7e, 0x1b, 0xe7, 0x29, 0xc6, 0xaf, 0x34, 0x66, 0x5e, - 0x8a, 0xb2, 0x36, 0xaa, 0x8d, 0x36, 0xbd, 0x56, 0x6d, 0xe1, 0x30, 0x50, - 0xed, 0x7d, 0xe0, 0xf7, 0x51, 0x0c, 0xea, 0x4b, 0xe3, 0x6b, 0x83, 0x55, - 0xeb, 0xb7, 0x28, 0xdc, 0xf8, 0x0d, 0x72, 0xff, 0x5e, 0x2d, 0xea, 0xab, - 0xb3, 0x55, 0xab, 0xf7, 0x6a, 0x0b, 0x38, 0xac, 0x55, 0x7b, 0x65, 0x06, - 0x5d, 0xc7, 0x6a, 0xde, 0x1e, 0x67, 0xb5, 0x2f, 0xe6, 0xf9, 0x9c, 0x58, - 0xed, 0x33, 0xfa, 0xce, 0x6a, 0xef, 0xa2, 0x7d, 0x6a, 0x63, 0xb5, 0x9d, - 0x77, 0xd9, 0xa2, 0xa0, 0xda, 0x57, 0xd3, 0x0d, 0xc6, 0x54, 0x2d, 0xea, - 0x05, 0xae, 0xac, 0xb6, 0x1e, 0xaa, 0xcd, 0xac, 0x06, 0x26, 0x83, 0x6a, - 0x15, 0x79, 0x0d, 0xaa, 0x41, 0x32, 0x0a, 0xac, 0xd6, 0x81, 0x29, 0x4d, - 0xa8, 0xe6, 0x51, 0x6d, 0x28, 0xab, 0x6d, 0x87, 0x6a, 0xcb, 0xa5, 0x6a, - 0xa1, 0xac, 0x56, 0x1f, 0xaa, 0xb5, 0x87, 0x6a, 0xfd, 0xdf, 0x5b, 0x6d, - 0x3b, 0x54, 0xfb, 0xf3, 0x50, 0xed, 0x8f, 0x43, 0xb5, 0xdf, 0x0e, 0xd5, - 0x7c, 0x59, 0xed, 0x4b, 0x31, 0x93, 0xf5, 0x2e, 0x65, 0x60, 0x26, 0x2b, - 0x43, 0xae, 0x8e, 0x33, 0xd9, 0x18, 0x72, 0x59, 0x35, 0x04, 0x65, 0x56, - 0xe1, 0xa3, 0xd6, 0xcd, 0x47, 0xe4, 0x7a, 0x6b, 0x8f, 0xe7, 0x6a, 0x93, - 0xad, 0x5b, 0xc4, 0x7d, 0xbf, 0x78, 0xc3, 0xc5, 0x88, 0xe9, 0xe3, 0xde, - 0xaa, 0x99, 0xa4, 0x6c, 0xef, 0xec, 0xc5, 0xcf, 0x89, 0x25, 0x76, 0xec, - 0xea, 0xd6, 0x12, 0xb9, 0xe2, 0x26, 0xb7, 0x6f, 0x09, 0x91, 0x1a, 0x8c, - 0x4d, 0x34, 0x7d, 0xd9, 0xe2, 0xd7, 0x9f, 0xe3, 0x06, 0xa9, 0xad, 0xed, - 0x7d, 0x95, 0xde, 0x45, 0x45, 0x58, 0xdf, 0xa1, 0xf0, 0x7e, 0x6d, 0xa2, - 0x91, 0x66, 0x34, 0x6a, 0xb0, 0x44, 0xa3, 0x8e, 0x6d, 0xcc, 0xb8, 0x45, - 0xdf, 0xc7, 0xd9, 0xc1, 0x59, 0xbe, 0xfb, 0xfe, 0x8c, 0xe1, 0x16, 0x73, - 0xcd, 0x45, 0x37, 0xd9, 0x6c, 0x68, 0x29, 0xaf, 0x46, 0x93, 0x1b, 0xc8, - 0x40, 0x5c, 0x94, 0x31, 0xc0, 0x92, 0x66, 0x04, 0xd6, 0xbc, 0x44, 0x83, - 0xbe, 0xa2, 0x12, 0x4f, 0x14, 0xda, 0x9c, 0x4e, 0x58, 0x1e, 0x5b, 0x68, - 0xb4, 0x66, 0x5b, 0xda, 0x40, 0x7a, 0x7b, 0x88, 0x0c, 0x38, 0x07, 0xc9, - 0x51, 0xcc, 0x1d, 0x8d, 0xa0, 0xd6, 0xf4, 0xd0, 0x80, 0x84, 0x66, 0x5a, - 0x09, 0xc5, 0x73, 0xa2, 0xd2, 0xfa, 0xbf, 0x44, 0x7e, 0xbb, 0x44, 0x1d, - 0x4b, 0x5d, 0x2b, 0x9d, 0x07, 0x4a, 0xea, 0x58, 0xda, 0x79, 0xba, 0x82, - 0xb1, 0x95, 0xe4, 0x15, 0x40, 0xc6, 0x7c, 0x53, 0x1d, 0x40, 0x36, 0x07, - 0x90, 0xed, 0x09, 0xc8, 0xa5, 0xb8, 0xf3, 0x87, 0x06, 0x0e, 0x76, 0x97, - 0xea, 0x70, 0xd7, 0x1c, 0x9a, 0xcb, 0x2e, 0xbe, 0xd1, 0x25, 0x0e, 0xb5, - 0x5f, 0xa0, 0x97, 0xb8, 0x83, 0x39, 0xc2, 0xf3, 0x4e, 0xcc, 0x9b, 0x22, - 0xdc, 0xe4, 0x52, 0xb4, 0x76, 0x27, 0xd1, 0x27, 0xe0, 0xd3, 0x35, 0xb4, - 0x5f, 0x94, 0x2c, 0x33, 0x19, 0x65, 0x26, 0x8c, 0x20, 0x14, 0x3c, 0x39, - 0xdd, 0x39, 0x36, 0x7e, 0x81, 0xef, 0xce, 0x87, 0x3b, 0x57, 0xde, 0x4d, - 0xe5, 0x5d, 0xe6, 0x65, 0xf9, 0x39, 0xb6, 0x9e, 0x06, 0x5f, 0x87, 0xc3, - 0xbc, 0xf4, 0x57, 0x84, 0xb3, 0xba, 0x90, 0x04, 0x00, 0xb6, 0x2b, 0x7a, - 0x85, 0x25, 0xf0, 0xea, 0x99, 0x40, 0x56, 0x6a, 0x48, 0xf1, 0x67, 0x36, - 0x0f, 0x69, 0x98, 0xaa, 0x2d, 0xdf, 0x6f, 0xf2, 0xe2, 0x66, 0xc1, 0x42, - 0x7e, 0xdc, 0xe4, 0x91, 0xcd, 0x53, 0x36, 0x6a, 0x64, 0x03, 0x6b, 0xcb, - 0x06, 0x9c, 0x4c, 0xc4, 0xc9, 0x0c, 0x1c, 0x52, 0x54, 0xfd, 0xa2, 0xda, - 0x0a, 0xab, 0x4f, 0x72, 0x0a, 0x55, 0x6b, 0xc2, 0xab, 0x74, 0x51, 0x6b, - 0xe6, 0x5a, 0x01, 0x8e, 0x67, 0x5c, 0x53, 0x4a, 0xe3, 0x71, 0x97, 0xf1, - 0x78, 0x3c, 0xa2, 0xc3, 0xab, 0xc0, 0x57, 0x5c, 0x7a, 0xea, 0xb3, 0x9b, - 0xd4, 0xdb, 0x55, 0x62, 0xcf, 0x17, 0x09, 0xde, 0xef, 0xa5, 0x56, 0xbc, - 0x91, 0x12, 0xf1, 0x42, 0x2a, 0x03, 0x04, 0xe6, 0xda, 0xce, 0x0e, 0x42, - 0x6d, 0xc0, 0xeb, 0x74, 0xfe, 0x66, 0x1f, 0x7d, 0x2d, 0x83, 0xd5, 0x1e, - 0x71, 0x61, 0xaa, 0x1d, 0x6a, 0x63, 0x07, 0xd6, 0x51, 0xcb, 0x83, 0x4e, - 0xb1, 0xea, 0x54, 0xf9, 0x45, 0xf6, 0xb2, 0x19, 0x32, 0x90, 0x8f, 0xae, - 0xe6, 0xc9, 0x6a, 0x0f, 0x06, 0xb8, 0x32, 0x37, 0xe3, 0x60, 0x5b, 0xae, - 0xa2, 0xb1, 0x67, 0xd5, 0x71, 0xf1, 0x4b, 0x43, 0x23, 0xd0, 0xdc, 0xd2, - 0x2e, 0x35, 0xe9, 0x30, 0xf8, 0xa1, 0xa3, 0x74, 0x86, 0xbd, 0xd0, 0x98, - 0x0e, 0x3a, 0x62, 0xaf, 0x52, 0x6b, 0xc7, 0x99, 0x91, 0xb1, 0x76, 0x4d, - 0x73, 0xc4, 0xa4, 0x53, 0xde, 0x87, 0x86, 0x5a, 0xb5, 0xe3, 0xd1, 0xed, - 0x1b, 0x28, 0x45, 0x6b, 0xfe, 0xee, 0x19, 0x9b, 0xdc, 0x83, 0x00, 0x29, - 0xe0, 0x3e, 0x4a, 0x31, 0xb0, 0xee, 0x8d, 0x15, 0x05, 0x22, 0xc7, 0x33, - 0xd9, 0x53, 0x64, 0xfd, 0x0a, 0x5a, 0xd1, 0x05, 0x86, 0xd6, 0xf7, 0xc6, - 0x45, 0x66, 0xd4, 0xee, 0x41, 0xee, 0x45, 0xf9, 0x02, 0x6e, 0x10, 0x0d, - 0x6f, 0x24, 0x92, 0xa7, 0x0e, 0x77, 0x21, 0x1d, 0xbf, 0xce, 0xf3, 0x24, - 0xbd, 0x11, 0xe5, 0x05, 0x15, 0x3a, 0x18, 0x14, 0x07, 0x2b, 0x66, 0x38, - 0xfe, 0x84, 0xe7, 0x50, 0x0c, 0xf1, 0xc9, 0x8a, 0xe9, 0x87, 0x9e, 0x5c, - 0xfa, 0x6a, 0x04, 0x4f, 0x6d, 0x44, 0x73, 0x8d, 0x9a, 0x6b, 0x03, 0x83, - 0xeb, 0xad, 0xd7, 0xe8, 0xec, 0xac, 0xce, 0xb2, 0xd7, 0xb4, 0xb3, 0x0c, - 0x35, 0x3d, 0x42, 0xa8, 0x8d, 0x48, 0xfc, 0x15, 0x83, 0xef, 0x44, 0x72, - 0x7a, 0x5d, 0x78, 0xd1, 0x0f, 0xd1, 0x1f, 0x3a, 0x0d, 0x14, 0x53, 0x9a, - 0x5c, 0x95, 0x41, 0xaf, 0xe8, 0x04, 0xc5, 0x7d, 0x25, 0x4f, 0x60, 0x72, - 0xe9, 0x24, 0x97, 0x83, 0x42, 0xc4, 0x82, 0x82, 0x3b, 0x93, 0xbb, 0x30, - 0x85, 0x32, 0x84, 0xf4, 0x52, 0x46, 0x80, 0x64, 0x6e, 0xe7, 0xcc, 0xc6, - 0xf5, 0xe3, 0x71, 0xa5, 0x36, 0xf0, 0x96, 0xf8, 0xb5, 0x74, 0xc4, 0x2f, - 0xa2, 0x69, 0x48, 0x6f, 0x85, 0xc0, 0x33, 0x12, 0x07, 0xfe, 0x5c, 0xca, - 0x2c, 0x6a, 0x37, 0xf4, 0x9d, 0x38, 0x05, 0x05, 0xb8, 0x0e, 0x6f, 0xfa, - 0x25, 0xef, 0x4a, 0xbc, 0xf8, 0x28, 0x9b, 0xe5, 0x7b, 0x6d, 0x9a, 0xb7, - 0xda, 0x34, 0x37, 0xdc, 0x34, 0xf0, 0x8f, 0x45, 0x78, 0x3d, 0xf5, 0xe4, - 0x4d, 0x2a, 0xfc, 0xd7, 0x40, 0xcb, 0xf3, 0x9f, 0xd2, 0xe6, 0x83, 0x54, - 0xfd, 0xa0, 0x2d, 0x1c, 0xb4, 0x85, 0x03, 0xb7, 0x30, 0x5d, 0xa5, 0xd2, - 0x93, 0xe8, 0x64, 0x09, 0x0a, 0x98, 0x53, 0x44, 0x88, 0x56, 0x6b, 0x4d, - 0xa4, 0xdb, 0x33, 0x3d, 0x4e, 0xba, 0x1c, 0xb0, 0xfa, 0xce, 0x8d, 0xbc, - 0x6e, 0xf2, 0x3c, 0x33, 0x7e, 0x58, 0xe1, 0xe7, 0x78, 0x4d, 0xab, 0x4f, - 0x41, 0x22, 0xf8, 0xd4, 0x53, 0x07, 0x97, 0x52, 0x4c, 0x5b, 0x58, 0xbb, - 0xe0, 0xe6, 0xee, 0xe3, 0x94, 0x19, 0x82, 0x2f, 0x74, 0x8e, 0xcf, 0xb4, - 0xf0, 0x59, 0x54, 0x41, 0x45, 0x97, 0xae, 0x82, 0x4b, 0x1a, 0x7e, 0xb4, - 0xa9, 0xe5, 0x4b, 0x94, 0x1d, 0xc3, 0x0e, 0xcd, 0x89, 0x6e, 0x88, 0xbb, - 0xd0, 0x66, 0xf8, 0x91, 0xd5, 0xdf, 0xff, 0x2d, 0xd5, 0x17, 0x56, 0x9f, - 0x59, 0xfd, 0xb4, 0xf3, 0x2f, 0x58, 0xbd, 0xa5, 0x6f, 0x8f, 0x63, 0x5f, - 0x38, 0xf6, 0x99, 0x63, 0x9f, 0x38, 0x76, 0x9b, 0xba, 0x86, 0x31, 0xc9, - 0xad, 0xd9, 0xce, 0xe2, 0x76, 0xb6, 0x38, 0x0c, 0x67, 0x33, 0x6f, 0xee, - 0x4c, 0x61, 0xfa, 0xe0, 0xb9, 0x5d, 0xb8, 0x40, 0xf2, 0x87, 0xca, 0x73, - 0xde, 0xb0, 0x58, 0xe1, 0x25, 0x1d, 0xd3, 0x9e, 0x78, 0xf1, 0xb0, 0x75, - 0x5f, 0xd8, 0xba, 0x05, 0x4e, 0x57, 0x01, 0x9d, 0xaf, 0x72, 0xe7, 0x6f, - 0x5d, 0xb8, 0x86, 0x53, 0xa7, 0x78, 0x51, 0xba, 0x83, 0xe3, 0x0a, 0xd0, - 0x03, 0x60, 0x71, 0x22, 0xf2, 0x16, 0x3b, 0x86, 0x0b, 0x29, 0x3e, 0xc8, - 0x62, 0x7a, 0xb6, 0x1c, 0xc4, 0xa3, 0x78, 0xa1, 0x8e, 0x5b, 0x86, 0x21, - 0x17, 0x08, 0x01, 0xb2, 0xea, 0x9f, 0xef, 0x57, 0x3d, 0x24, 0xf7, 0x39, - 0xaa, 0x87, 0xe4, 0x3f, 0x97, 0x8b, 0x5c, 0x0e, 0x74, 0xb9, 0xd7, 0xbf, - 0x67, 0xeb, 0xb7, 0x56, 0x57, 0xcc, 0x4c, 0xc3, 0x80, 0x11, 0x85, 0xd4, - 0x9c, 0x4e, 0xdd, 0x09, 0xd2, 0x36, 0x9c, 0xf9, 0x36, 0x7d, 0xe7, 0xcc, - 0xb0, 0xae, 0x0a, 0xd8, 0x71, 0x51, 0x1e, 0xcf, 0x1b, 0xd6, 0x7e, 0xaf, - 0x99, 0x72, 0xdd, 0xb7, 0x2b, 0xfb, 0x5d, 0x58, 0x77, 0x82, 0x36, 0x33, - 0xd1, 0x66, 0x94, 0x57, 0xb8, 0x21, 0x76, 0x29, 0x00, 0xa9, 0xe3, 0xac, - 0xf5, 0x98, 0x54, 0xfb, 0x79, 0x85, 0x31, 0x26, 0xc9, 0x67, 0x74, 0xf2, - 0x0c, 0x61, 0xba, 0x07, 0xae, 0x8e, 0x4b, 0xab, 0x40, 0x83, 0x33, 0x9a, - 0x5f, 0x4e, 0xe2, 0x9c, 0xa6, 0x63, 0xc0, 0x8b, 0xbc, 0xd0, 0xe2, 0x24, - 0xda, 0x1a, 0x62, 0x1f, 0x71, 0x2c, 0x91, 0x6e, 0x39, 0x3c, 0x12, 0x87, - 0x1c, 0x99, 0xfc, 0xd2, 0x05, 0x05, 0x3c, 0xe5, 0x78, 0xb7, 0x96, 0xdf, - 0x82, 0xcb, 0x24, 0x4b, 0xa4, 0x4a, 0xf3, 0xcd, 0x40, 0x37, 0x2d, 0x0b, - 0x30, 0x99, 0x18, 0x5c, 0xa7, 0xd5, 0x3b, 0x2d, 0xfe, 0x9c, 0x70, 0xa3, - 0x08, 0xe5, 0xeb, 0x31, 0x67, 0xae, 0xc4, 0xbc, 0x5f, 0xa3, 0x38, 0x47, - 0x9f, 0xb6, 0x49, 0xde, 0x96, 0x94, 0xfd, 0xaf, 0x58, 0xfc, 0x18, 0xe6, - 0xfc, 0x7b, 0x17, 0xbf, 0x2b, 0xc9, 0x53, 0x9f, 0x82, 0xf2, 0x3e, 0xdf, - 0x82, 0xc8, 0x55, 0x0e, 0xec, 0x7c, 0x59, 0xf2, 0x46, 0xb2, 0x54, 0xf1, - 0x83, 0x96, 0x72, 0x40, 0x8f, 0xb7, 0xba, 0x9d, 0xb1, 0x0f, 0x93, 0x43, - 0x5f, 0x83, 0x23, 0x6d, 0x35, 0xb7, 0x60, 0x0b, 0x5b, 0xc2, 0xd4, 0x41, - 0xa7, 0x15, 0xb5, 0x39, 0xe5, 0x6d, 0x47, 0x59, 0x46, 0x3c, 0x6d, 0xc0, - 0x60, 0x72, 0x14, 0x64, 0xcd, 0xec, 0x82, 0x74, 0x07, 0xd8, 0x18, 0x82, - 0x1c, 0x7d, 0x94, 0xdc, 0x92, 0xa0, 0x25, 0xc5, 0xcd, 0x61, 0xe9, 0x81, - 0x07, 0x79, 0x02, 0x31, 0x98, 0x20, 0x67, 0x5e, 0x72, 0xfc, 0xe8, 0x2d, - 0xa9, 0x24, 0xd7, 0xb2, 0x58, 0xdc, 0x59, 0x6c, 0x55, 0xaf, 0xc9, 0x4c, - 0x28, 0x4e, 0x47, 0x5b, 0x8a, 0xfa, 0x8a, 0xdb, 0xf6, 0x10, 0xcc, 0x78, - 0x40, 0x0d, 0x66, 0xb1, 0x27, 0x4d, 0xf7, 0xe9, 0xad, 0x8b, 0x85, 0x83, - 0x54, 0x68, 0xe1, 0x0d, 0xad, 0x2c, 0x12, 0x6f, 0xc8, 0x21, 0x3e, 0x91, - 0x27, 0xff, 0x41, 0x86, 0xf2, 0x1b, 0x19, 0x09, 0x7d, 0x3b, 0x7f, 0x52, - 0xc4, 0xbf, 0xad, 0xf8, 0x91, 0xa0, 0xe8, 0x53, 0xf1, 0x3f, 0xba, 0x58, - 0xa8, 0x28, 0xc1, 0x8a, 0x02, 0xd5, 0x3d, 0x11, 0xf9, 0x13, 0x8b, 0x6f, - 0x28, 0x4f, 0x5c, 0xda, 0x25, 0x4d, 0x96, 0x9b, 0xca, 0x3d, 0xd6, 0xa4, - 0x20, 0x53, 0x13, 0xe6, 0x9b, 0x90, 0x42, 0x15, 0x25, 0x46, 0x3d, 0x47, - 0x92, 0x0e, 0x8f, 0x66, 0x31, 0x94, 0xb2, 0x1c, 0xb7, 0xcb, 0xe2, 0x01, - 0xc5, 0x92, 0xa2, 0x44, 0xd7, 0x92, 0xac, 0x8e, 0x62, 0xd2, 0x33, 0x7e, - 0xc4, 0x4e, 0x42, 0xd0, 0x20, 0x92, 0xf4, 0x43, 0x7f, 0x73, 0x62, 0x80, - 0x4f, 0xff, 0xaf, 0xff, 0x8f, 0x6b, 0xf8, 0xe3, 0xff, 0x3f, 0x86, 0x91, - 0xfe, 0x8a, 0xff, 0xff, 0x95, 0x7e, 0x8f, 0x61, 0x3e, 0x1f, 0xc3, 0xff, - 0xf0, 0xb4, 0xe3, 0x9e, 0xfe, 0x5f, 0xfc, 0xef, 0x22, 0x8f, 0xb7, 0xa4, - 0x83, 0xc6, 0x26, 0x8f, 0x53, 0x8f, 0xd4, 0x98, 0xe8, 0x44, 0xe1, 0x7f, - 0x24, 0x2e, 0x51, 0x37, 0x08, 0x14, 0x3e, 0xa4, 0x3a, 0xe4, 0xf7, 0xe7, - 0xbc, 0xa5, 0x93, 0x62, 0x5b, 0x8e, 0xd2, 0xbd, 0xf4, 0x12, 0x19, 0xcb, - 0xa2, 0x54, 0x1f, 0xff, 0x06, 0x9a, 0xb3, 0x1b, 0x98, 0x26, 0xec, 0x58, - 0xda, 0xd8, 0x4b, 0x1f, 0x74, 0x86, 0xed, 0x44, 0x49, 0x63, 0x48, 0x36, - 0xb1, 0x3e, 0x59, 0x21, 0xdf, 0x53, 0x4e, 0x79, 0x45, 0x2f, 0x03, 0xcd, - 0x45, 0x32, 0x13, 0xc9, 0xba, 0x24, 0xab, 0xd2, 0x79, 0x31, 0xad, 0x26, - 0x8c, 0xdf, 0x8a, 0x40, 0x35, 0x66, 0x8f, 0xb1, 0x3e, 0xa6, 0xe2, 0x9f, - 0xa8, 0xdc, 0x63, 0xd1, 0xc6, 0xa3, 0xf0, 0x25, 0xc3, 0xf8, 0x0f, 0x2a, - 0x06, 0x1a, 0xce, 0xd9, 0x3b, 0xda, 0x63, 0x5a, 0xdc, 0xbf, 0x60, 0xf1, - 0x67, 0x3a, 0xce, 0x0c, 0x53, 0x6b, 0x62, 0x6a, 0x4b, 0x4c, 0x3d, 0x29, - 0xbe, 0x88, 0xc8, 0x43, 0x12, 0xd7, 0x9b, 0xab, 0x4a, 0xed, 0x5b, 0x3a, - 0x18, 0xf8, 0x56, 0xea, 0xea, 0x61, 0xbc, 0xfb, 0x18, 0x1f, 0x6b, 0x4d, - 0x6c, 0x9f, 0x28, 0xb6, 0x4f, 0x14, 0xdb, 0xbf, 0x84, 0xa0, 0x57, 0x8b, - 0x4e, 0xad, 0x9f, 0x10, 0xdf, 0x37, 0x5a, 0x3d, 0xff, 0xa4, 0xd5, 0xf3, - 0x86, 0x47, 0x47, 0x77, 0xd8, 0xef, 0x8b, 0xc7, 0xfb, 0xb3, 0xaf, 0xe9, - 0xcd, 0x6a, 0xb0, 0xba, 0x4b, 0x0b, 0x7b, 0xc4, 0xd0, 0x9b, 0xad, 0x7d, - 0x75, 0x50, 0xd9, 0xa7, 0x1a, 0xea, 0x44, 0xfc, 0x18, 0xc6, 0x9e, 0x3f, - 0x0a, 0x35, 0xad, 0x85, 0x29, 0x2b, 0x3d, 0xd6, 0xa1, 0x81, 0x64, 0xc9, - 0xa5, 0x77, 0xf3, 0xa4, 0x04, 0x59, 0x4b, 0x4b, 0x56, 0x86, 0x9e, 0xaa, - 0xff, 0x4a, 0xd5, 0x1f, 0xc7, 0xef, 0x97, 0x9c, 0xba, 0xa7, 0xea, 0x3f, - 0xa7, 0xfa, 0x10, 0x9e, 0x7e, 0x3f, 0xe7, 0x77, 0x90, 0x5b, 0x78, 0x4b, - 0xb1, 0x85, 0x52, 0xcc, 0x53, 0xe1, 0x53, 0xe1, 0x23, 0x2a, 0x0c, 0xc9, - 0x2d, 0x32, 0x27, 0x0a, 0x62, 0x98, 0xfc, 0xa8, 0x0b, 0x3d, 0x0a, 0xdf, - 0xa1, 0x90, 0xc7, 0xf4, 0x7f, 0xbd, 0x56, 0x38, 0xc8, 0x23, 0xd6, 0xa6, - 0x57, 0xd9, 0x5f, 0x42, 0x5d, 0x7c, 0x0f, 0xc3, 0xb0, 0x69, 0x6f, 0x3d, - 0x4e, 0xc0, 0x6a, 0xe1, 0x34, 0xa6, 0x7f, 0xab, 0x86, 0xb8, 0xf9, 0x02, - 0x1e, 0xe6, 0x90, 0xad, 0xc1, 0xd2, 0x11, 0x90, 0x3b, 0xc9, 0x75, 0x1e, - 0xd0, 0x63, 0xcb, 0xe5, 0x57, 0x77, 0x65, 0x0a, 0x1e, 0x45, 0xc8, 0x25, - 0x6c, 0xfb, 0xa0, 0x97, 0x27, 0xcd, 0x73, 0xe5, 0x6d, 0xa8, 0x66, 0x9f, - 0xc6, 0xd2, 0x30, 0x60, 0x72, 0xd4, 0x72, 0xc9, 0x49, 0x94, 0x82, 0x5e, - 0x5a, 0x1a, 0xbc, 0x63, 0xb1, 0x32, 0x5a, 0xb2, 0x84, 0x89, 0xac, 0x63, - 0x6b, 0x69, 0x6f, 0x47, 0x46, 0x6f, 0x62, 0x32, 0xf0, 0x80, 0x9d, 0x40, - 0x06, 0xb8, 0x86, 0x65, 0x20, 0x68, 0xa5, 0x55, 0x46, 0x30, 0xcb, 0x37, - 0x30, 0x28, 0x66, 0x54, 0xca, 0xe8, 0xcc, 0x43, 0x66, 0x19, 0x53, 0x8b, - 0x25, 0x58, 0x1d, 0x97, 0x6d, 0x6c, 0xe1, 0xed, 0x42, 0x46, 0x03, 0xed, - 0x1b, 0xaf, 0x47, 0x51, 0xb8, 0x47, 0x06, 0xb4, 0x2d, 0xcb, 0xb0, 0xbf, - 0x4a, 0x19, 0x1d, 0x96, 0x02, 0x11, 0xb9, 0x5c, 0x1e, 0xcb, 0xa8, 0xe1, - 0xb7, 0xcb, 0x19, 0x0d, 0x66, 0x18, 0xdf, 0x72, 0x25, 0x9c, 0xe1, 0x0c, - 0x70, 0xbc, 0xa9, 0x94, 0x21, 0x47, 0x66, 0xc5, 0x28, 0x01, 0x93, 0xf1, - 0x1d, 0x96, 0x7b, 0x64, 0x86, 0x21, 0xcf, 0xdc, 0x30, 0x20, 0xc3, 0x29, - 0xd6, 0x29, 0x65, 0x9c, 0xce, 0x4d, 0xa5, 0x0c, 0x46, 0xcb, 0xe0, 0xb4, - 0xc2, 0x98, 0xd1, 0x33, 0xa3, 0xa6, 0xe9, 0xc2, 0xc2, 0x70, 0x92, 0x5f, - 0x15, 0xb6, 0x85, 0xe5, 0x98, 0x71, 0x58, 0xcd, 0x32, 0xa3, 0x63, 0x34, - 0xa4, 0x05, 0x8e, 0xc0, 0x11, 0x82, 0x0c, 0x04, 0xdf, 0xc8, 0x33, 0x02, - 0xbc, 0x1f, 0xb3, 0x4b, 0x58, 0x1b, 0x21, 0x09, 0x15, 0xda, 0x53, 0xc7, - 0x8c, 0x4d, 0x19, 0xd3, 0xb5, 0x8c, 0xb3, 0x2a, 0x29, 0xe3, 0xa4, 0x95, - 0xa2, 0xd9, 0x63, 0xc7, 0x3e, 0x9d, 0x76, 0x3d, 0x8d, 0xa5, 0xbb, 0x88, - 0xcc, 0xc8, 0x58, 0x4e, 0x67, 0x2c, 0x4d, 0xe1, 0x71, 0x4e, 0xeb, 0xd3, - 0x59, 0x4f, 0xcb, 0xd0, 0x95, 0x48, 0xcc, 0x95, 0xd3, 0x52, 0x2e, 0xa7, - 0x8b, 0x9d, 0x56, 0xff, 0x88, 0x0e, 0xb5, 0x10, 0xa6, 0xc0, 0x20, 0xa1, - 0xd4, 0x39, 0x36, 0x0b, 0x0b, 0x97, 0x53, 0x3c, 0x3d, 0xc3, 0xe4, 0x4d, - 0x19, 0xd3, 0x29, 0xf2, 0x6b, 0x37, 0x64, 0x2c, 0x3e, 0xdd, 0x40, 0x8b, - 0xb6, 0xd8, 0x71, 0xcf, 0xa5, 0x4d, 0xd8, 0x73, 0x9b, 0xd6, 0xda, 0xa6, - 0xdd, 0xf9, 0x46, 0x4e, 0x93, 0x72, 0xb2, 0xf7, 0x45, 0x0c, 0x9a, 0x53, - 0x72, 0x51, 0x10, 0x94, 0x13, 0x0a, 0xd3, 0x65, 0x1a, 0x74, 0xb6, 0x8e, - 0x27, 0x64, 0xcb, 0xd3, 0x20, 0x50, 0x10, 0x36, 0x64, 0xc8, 0xdf, 0x1d, - 0xa1, 0x2b, 0x63, 0x16, 0xca, 0x3d, 0xfd, 0x7f, 0xfa, 0xff, 0xf4, 0xff, - 0xda, 0xff, 0xbf, 0xe9, 0xe7, 0xe2, 0xcf, 0xc8, 0xbe, 0xb5, 0xab, 0x17, - 0x3c, 0x2d, 0xbb, 0x0b, 0x62, 0x07, 0x87, 0xd7, 0x4a, 0xef, 0xce, 0xa6, - 0x68, 0x35, 0xc6, 0xeb, 0xde, 0x2e, 0xd7, 0x7b, 0x66, 0x7b, 0xbb, 0x2c, - 0xdf, 0xa2, 0x99, 0x1e, 0x94, 0x6d, 0x63, 0x28, 0x86, 0xd6, 0xde, 0x3b, - 0x7b, 0x48, 0x43, 0xb0, 0x31, 0x54, 0x7f, 0x29, 0x7b, 0x4c, 0x23, 0xb3, - 0xa1, 0xd5, 0xf7, 0xce, 0xde, 0xf2, 0x10, 0x6c, 0x68, 0xfe, 0xde, 0xd9, - 0x73, 0xce, 0x0e, 0x79, 0x64, 0x40, 0xa2, 0x78, 0x36, 0x70, 0x7c, 0x65, - 0x31, 0x66, 0xef, 0x74, 0xd8, 0xde, 0x6c, 0xcc, 0xd9, 0x43, 0xce, 0x5e, - 0xec, 0xb8, 0xc3, 0x94, 0xdd, 0x45, 0x32, 0xbe, 0xf3, 0x77, 0xcb, 0xb6, - 0x4f, 0xd7, 0xf5, 0xc8, 0x7e, 0x67, 0xd9, 0x6b, 0x91, 0x3d, 0x2a, 0xfb, - 0x23, 0xcc, 0xcf, 0xd1, 0xae, 0x6b, 0xaf, 0xec, 0xed, 0x23, 0x7b, 0x75, - 0x96, 0x3d, 0xe5, 0xec, 0x2d, 0x65, 0xb7, 0x30, 0x35, 0xc7, 0xe9, 0x9c, - 0x61, 0x85, 0xfe, 0x78, 0x92, 0xbd, 0x14, 0xd9, 0xf1, 0xa5, 0x51, 0x65, - 0x7b, 0x63, 0x71, 0x31, 0x46, 0x6d, 0x17, 0xec, 0xe7, 0x38, 0xb2, 0xdb, - 0xb3, 0x07, 0x65, 0x3f, 0x37, 0x41, 0xc1, 0xde, 0xba, 0x8b, 0x6f, 0xe8, - 0xed, 0x43, 0x78, 0xad, 0xec, 0xea, 0x52, 0xf6, 0x9a, 0xb2, 0x3b, 0x13, - 0xff, 0x9f, 0xc5, 0xec, 0x67, 0x66, 0xe4, 0x5e, 0x52, 0x76, 0x7f, 0x29, - 0x7b, 0x52, 0xf6, 0x60, 0x2f, 0x7f, 0x98, 0x4d, 0x7b, 0xc1, 0x4b, 0x86, - 0x95, 0xb2, 0x9b, 0x22, 0xdb, 0x2b, 0x3b, 0xa4, 0xec, 0xf8, 0x6e, 0xa1, - 0xc7, 0xf1, 0x90, 0x83, 0x8f, 0xd9, 0x53, 0xca, 0x0e, 0x39, 0xbb, 0xbd, - 0x90, 0xdd, 0x47, 0xd9, 0xc2, 0x34, 0x9b, 0x25, 0xbe, 0x69, 0x48, 0x57, - 0xd9, 0x49, 0x76, 0x55, 0x64, 0x77, 0xcc, 0xb6, 0x3c, 0x44, 0xec, 0x22, - 0x6f, 0x28, 0xb2, 0x6b, 0x65, 0xf7, 0x08, 0xa1, 0x89, 0xd9, 0xb5, 0xb2, - 0xdb, 0xe8, 0x7b, 0x43, 0xb6, 0x8b, 0x3a, 0xd6, 0x5c, 0x64, 0xbb, 0xb3, - 0xec, 0x26, 0xc6, 0xf9, 0x32, 0xdb, 0xc7, 0xd7, 0x88, 0x95, 0x3d, 0xfb, - 0xad, 0xc8, 0x9e, 0xce, 0xb3, 0xfb, 0x88, 0x1f, 0xc8, 0xae, 0x0d, 0x3f, - 0x94, 0xfd, 0x92, 0xee, 0x1e, 0xcb, 0x5e, 0xcf, 0xb3, 0x2b, 0x7b, 0xd9, - 0x14, 0xd9, 0x11, 0x73, 0x53, 0xf6, 0xd7, 0xb0, 0x14, 0xd9, 0xc3, 0x79, - 0x76, 0x9b, 0xb3, 0x1d, 0xa1, 0x2a, 0xc8, 0xda, 0xe5, 0xec, 0xf9, 0x42, - 0xb6, 0xcf, 0xd9, 0xcd, 0x31, 0x7b, 0xca, 0xd9, 0xdb, 0x85, 0xec, 0xba, - 0xc8, 0xee, 0x0f, 0xd9, 0x6b, 0x91, 0x3d, 0x5e, 0xc8, 0xee, 0x72, 0x76, - 0x75, 0xcc, 0x1e, 0x72, 0xf6, 0x72, 0x21, 0xdb, 0x15, 0xd9, 0xed, 0x21, - 0x7b, 0x2e, 0xb2, 0xdd, 0x85, 0xec, 0xa6, 0xc8, 0xf6, 0x65, 0xf6, 0x56, - 0x64, 0x4f, 0xca, 0xae, 0x8b, 0xec, 0xfe, 0x5a, 0xf6, 0x98, 0xb3, 0xd7, - 0x94, 0xdd, 0xe5, 0x6c, 0x7d, 0x98, 0xc4, 0x48, 0x1f, 0xd0, 0x95, 0x14, - 0x7d, 0x24, 0x59, 0x9c, 0x5d, 0xaa, 0x67, 0x04, 0x7b, 0x15, 0x8d, 0x14, - 0x09, 0x1d, 0x48, 0x8f, 0xc7, 0x7c, 0x6e, 0xa2, 0x01, 0xa0, 0x26, 0x6f, - 0x15, 0x7a, 0x56, 0xe8, 0x58, 0x41, 0x8a, 0x94, 0xdc, 0xa7, 0x35, 0x2b, - 0xc8, 0x82, 0x0b, 0x9e, 0xe2, 0xb2, 0x85, 0xb7, 0x67, 0x85, 0x8e, 0x15, - 0xa4, 0x67, 0x35, 0xac, 0x50, 0xb3, 0x02, 0xf8, 0xc8, 0x40, 0x00, 0x13, - 0x01, 0xcc, 0x04, 0xb0, 0x38, 0xd9, 0x23, 0x48, 0xe6, 0xc5, 0x05, 0x06, - 0x02, 0xd0, 0x49, 0xa4, 0x33, 0x01, 0x2c, 0x04, 0xa0, 0x57, 0xfc, 0x83, - 0x98, 0xd6, 0x40, 0x00, 0x13, 0x01, 0x28, 0x4a, 0x77, 0x25, 0x80, 0x4d, - 0x6c, 0x51, 0xbc, 0x65, 0x24, 0x80, 0x89, 0x00, 0x14, 0xf4, 0xaf, 0x63, - 0x2d, 0xf5, 0xad, 0x56, 0x9d, 0x2f, 0x69, 0x0a, 0x11, 0x2a, 0x78, 0x56, - 0x88, 0x00, 0xfe, 0xa4, 0x49, 0xe5, 0x2b, 0x5f, 0x89, 0xd9, 0x02, 0x5f, - 0x56, 0xe8, 0xf9, 0xda, 0xc0, 0x2b, 0x53, 0x9c, 0x82, 0xbd, 0x63, 0x19, - 0x2b, 0xbe, 0xe7, 0x5e, 0xfd, 0x62, 0x6f, 0x09, 0x5a, 0x58, 0x08, 0x2a, - 0xf6, 0xf4, 0xfb, 0x75, 0xa4, 0x02, 0x2f, 0xf9, 0x16, 0xc4, 0x1b, 0xc6, - 0xf3, 0xfd, 0xce, 0x17, 0x0f, 0xe6, 0x40, 0xfa, 0xd2, 0x83, 0xb4, 0xc5, - 0x43, 0x0d, 0x0c, 0x40, 0xcb, 0x37, 0x11, 0x6a, 0x86, 0x05, 0x3f, 0x23, - 0xd1, 0x1c, 0x69, 0x75, 0xdf, 0xe9, 0xd5, 0x68, 0x00, 0x3a, 0xc4, 0x09, - 0xef, 0xd4, 0x79, 0x31, 0x00, 0x35, 0x1c, 0x94, 0xfb, 0xd3, 0x78, 0x4d, - 0xc3, 0x31, 0xee, 0x70, 0x27, 0x7a, 0xc6, 0x2d, 0xf6, 0x66, 0xec, 0x7d, - 0xac, 0xbd, 0x19, 0xfb, 0xda, 0xc3, 0x4e, 0xd3, 0xc0, 0x3a, 0x2a, 0x44, - 0x16, 0xc7, 0xfe, 0xbd, 0x08, 0x08, 0x4e, 0x78, 0x63, 0x00, 0x3a, 0x30, - 0xa5, 0x9d, 0x48, 0xda, 0xe1, 0xfb, 0x3b, 0x45, 0xb2, 0xaf, 0xee, 0x4d, - 0x15, 0xbe, 0xd7, 0x17, 0x15, 0xc5, 0x57, 0x01, 0x04, 0xe7, 0x26, 0xc0, - 0x2a, 0xf5, 0x21, 0xe0, 0xad, 0xa2, 0x3f, 0x0d, 0x40, 0x0d, 0x6e, 0x3c, - 0x90, 0x87, 0xe7, 0xb9, 0xef, 0x39, 0xf7, 0x58, 0xb4, 0xfc, 0x1a, 0x5a, - 0xcd, 0x45, 0x4b, 0xd2, 0x1e, 0x16, 0x69, 0x60, 0x05, 0x5a, 0xb8, 0xce, - 0xd0, 0x43, 0xaf, 0x7c, 0xac, 0xd7, 0xf1, 0xaa, 0x21, 0x80, 0x33, 0x84, - 0xf4, 0x00, 0x80, 0x0a, 0x6b, 0xc6, 0xe4, 0x86, 0x00, 0x6a, 0x02, 0xa8, - 0x08, 0x00, 0x15, 0x26, 0x56, 0x98, 0x59, 0x41, 0x7b, 0x46, 0xae, 0xee, - 0x2d, 0xbf, 0x9c, 0x72, 0xdc, 0x6c, 0x63, 0x76, 0xb7, 0x5c, 0xdc, 0xa5, - 0xab, 0xcb, 0x6f, 0xf2, 0xf5, 0x04, 0xd0, 0x11, 0x40, 0x43, 0x00, 0x35, - 0x01, 0x24, 0xba, 0xe0, 0x43, 0x0e, 0x55, 0x5f, 0x59, 0x21, 0xc9, 0x62, - 0x12, 0xec, 0x06, 0x56, 0x10, 0x05, 0x9a, 0x58, 0x61, 0x66, 0x85, 0x85, - 0x15, 0x24, 0x09, 0x6e, 0x22, 0x5d, 0x26, 0xd1, 0x6e, 0xe9, 0xa8, 0xac, - 0xf8, 0xf0, 0xcc, 0xb2, 0x85, 0x54, 0x6b, 0xcd, 0x8d, 0x8b, 0xd6, 0x88, - 0x84, 0x68, 0x3e, 0xb9, 0x30, 0xda, 0xc7, 0xda, 0xd7, 0xda, 0xae, 0x58, - 0x2f, 0xbd, 0x78, 0x96, 0x5e, 0xca, 0xe1, 0xee, 0x4d, 0x91, 0xf1, 0x1d, - 0xff, 0x3c, 0xf6, 0xdb, 0x48, 0x10, 0xcf, 0xb8, 0xf3, 0x9f, 0x13, 0x47, - 0x5a, 0x30, 0x8f, 0xd3, 0x17, 0x0a, 0xf5, 0x4a, 0xdf, 0x17, 0x92, 0x22, - 0x05, 0xfd, 0x7e, 0x08, 0xb7, 0xbc, 0x54, 0xd5, 0xa6, 0x20, 0x9b, 0x62, - 0xdd, 0xc7, 0xbc, 0xac, 0x5c, 0xe6, 0x47, 0xe7, 0xa3, 0x7b, 0xaa, 0xfe, - 0xcf, 0xae, 0xee, 0x51, 0x5d, 0x2f, 0x12, 0x1e, 0x5e, 0xa2, 0xbc, 0x0b, - 0xe7, 0x3b, 0x1e, 0x7d, 0xde, 0x73, 0xcb, 0x84, 0xe3, 0x3b, 0xb8, 0x75, - 0x7e, 0xff, 0x8d, 0x3b, 0x0e, 0xc7, 0xc1, 0xc3, 0x78, 0x17, 0x39, 0xa6, - 0x7d, 0x60, 0xb9, 0x09, 0x3a, 0x17, 0x36, 0xbd, 0x8a, 0x6d, 0x12, 0x38, - 0x03, 0xe0, 0xac, 0xc7, 0x36, 0x9e, 0x90, 0x42, 0xe9, 0xc8, 0x21, 0x06, - 0xc7, 0xc7, 0x1c, 0x1f, 0x73, 0x7c, 0x0c, 0xe9, 0x98, 0x25, 0x19, 0x16, - 0x3b, 0x4e, 0x93, 0xc1, 0x71, 0xa0, 0x46, 0xa6, 0xf2, 0xb7, 0x24, 0x5a, - 0xae, 0x1f, 0x5d, 0xaa, 0x2d, 0x26, 0x20, 0x61, 0xa3, 0x3f, 0x34, 0x3e, - 0x4a, 0xf1, 0x6f, 0x0f, 0x7d, 0x96, 0x47, 0x26, 0xbd, 0x04, 0x2b, 0x65, - 0x9d, 0xc5, 0x23, 0x12, 0x05, 0xfb, 0xeb, 0x6d, 0x1d, 0xa3, 0x3d, 0x3d, - 0x27, 0xb0, 0xe3, 0xab, 0x02, 0xdd, 0xe5, 0x37, 0x09, 0xaa, 0x93, 0xb7, - 0x75, 0xda, 0x1f, 0xf1, 0xb6, 0x4e, 0x75, 0xe5, 0x15, 0x89, 0xfe, 0x38, - 0xb3, 0xc2, 0x28, 0x21, 0xe2, 0xdf, 0x54, 0x7c, 0xb1, 0x6b, 0x0f, 0x1b, - 0xd8, 0x79, 0xb1, 0x66, 0xed, 0xd2, 0xa4, 0x56, 0x77, 0xbe, 0xdc, 0x41, - 0x1f, 0xde, 0xe9, 0xcb, 0x1d, 0xfa, 0x3e, 0xd1, 0xc9, 0x7a, 0x9f, 0xa0, - 0xc3, 0x76, 0x82, 0x2d, 0x23, 0x8a, 0xd3, 0x97, 0x91, 0x58, 0x3c, 0x1c, - 0xf9, 0xe0, 0x24, 0xfc, 0x3f, 0x60, 0xea, 0x92, 0x9c, 0xad, 0xb4, 0xc6, - 0x25, 0x6f, 0x6b, 0x4b, 0xcb, 0xd8, 0x53, 0xf1, 0xaf, 0x56, 0xec, 0x9e, - 0xe4, 0x2a, 0x60, 0xf8, 0x2f, 0xc7, 0x5f, 0x9f, 0xaa, 0xff, 0x33, 0xab, - 0xff, 0xe3, 0xe5, 0x2a, 0x85, 0xfb, 0x2c, 0xa4, 0x6f, 0x0f, 0x4d, 0xe7, - 0x07, 0xa5, 0x3e, 0xa5, 0xd3, 0x49, 0x3a, 0x20, 0x05, 0x79, 0xc5, 0x37, - 0xdc, 0x1c, 0xc3, 0x59, 0x62, 0x4a, 0xea, 0xfa, 0xff, 0x98, 0xfe, 0x17, - 0xd3, 0xff, 0xd4, 0x90, 0x8f, 0x14, 0x53, 0x87, 0x53, 0xa4, 0xb7, 0x38, - 0x86, 0xe3, 0xcc, 0xea, 0x44, 0x95, 0x14, 0xfa, 0x28, 0xd7, 0x8a, 0x9c, - 0x26, 0xac, 0x9e, 0xc4, 0x3e, 0x56, 0x97, 0xb4, 0xc0, 0x0f, 0xab, 0x62, - 0xbd, 0x1b, 0xc6, 0x24, 0x34, 0x27, 0x07, 0x73, 0x34, 0x67, 0xa7, 0xc9, - 0x5c, 0x3e, 0xd7, 0xc3, 0xa7, 0x93, 0x22, 0x2e, 0x62, 0x5d, 0x9d, 0x5e, - 0x0f, 0x39, 0xa5, 0xb4, 0xd7, 0x4e, 0x54, 0xf9, 0x1e, 0x87, 0x92, 0x54, - 0xf7, 0x6c, 0xfd, 0x8e, 0xce, 0x9f, 0x6f, 0x99, 0x95, 0x63, 0xbf, 0x76, - 0x10, 0xcf, 0x0b, 0xda, 0x0d, 0x5b, 0xd8, 0x7b, 0xf4, 0x09, 0x2a, 0x7d, - 0x99, 0x4a, 0xd1, 0xfc, 0x92, 0xcf, 0x9f, 0x71, 0xa1, 0x24, 0x98, 0x71, - 0xe1, 0xa6, 0xe3, 0xba, 0x67, 0x49, 0xcc, 0x33, 0x45, 0xf1, 0x7c, 0xc2, - 0x41, 0x55, 0x5d, 0x9c, 0xf4, 0xc2, 0x11, 0x48, 0xb6, 0xee, 0x13, 0x39, - 0xe9, 0x6b, 0xae, 0xfb, 0x73, 0xae, 0xfb, 0x0b, 0xae, 0x7b, 0x8b, 0x75, - 0xdf, 0x18, 0xdc, 0xb3, 0x5e, 0x1c, 0xbb, 0x67, 0x28, 0x4b, 0x7e, 0x0d, - 0xe8, 0x2d, 0x67, 0xfe, 0xe5, 0x5f, 0x5b, 0xf7, 0x0f, 0x0f, 0x59, 0xb8, - 0x1f, 0x86, 0x36, 0xff, 0xf8, 0xea, 0x55, 0x7e, 0x0d, 0x46, 0xdc, 0x66, - 0xb0, 0xb7, 0xbb, 0x22, 0xc1, 0xaa, 0xe9, 0x49, 0x0e, 0xd9, 0xb6, 0x27, - 0x63, 0xa1, 0xf8, 0x98, 0x34, 0xda, 0x64, 0xc5, 0x94, 0x75, 0x13, 0xc8, - 0x38, 0x88, 0xd4, 0x01, 0x47, 0xf5, 0x39, 0x16, 0xea, 0xb7, 0xe9, 0x20, - 0x1c, 0xa9, 0xbd, 0xc4, 0xdc, 0xca, 0x6c, 0xc9, 0x38, 0x75, 0xa3, 0xb1, - 0xed, 0x13, 0x3d, 0x50, 0x81, 0x0c, 0xc9, 0x76, 0x57, 0xc5, 0xa3, 0xd0, - 0xec, 0x53, 0xcf, 0xb6, 0xe9, 0xc4, 0xce, 0xde, 0x62, 0x4f, 0xde, 0xe7, - 0x03, 0x6a, 0x35, 0x3f, 0xca, 0xd4, 0x45, 0x24, 0x37, 0xe4, 0x7e, 0x0b, - 0x3a, 0x20, 0x56, 0xf9, 0x85, 0xb8, 0xce, 0x4f, 0xdb, 0xda, 0xc9, 0xef, - 0xee, 0xec, 0x33, 0x61, 0xfa, 0x00, 0xee, 0x07, 0x12, 0x11, 0xea, 0x78, - 0xa7, 0x5f, 0x74, 0xf3, 0x90, 0x58, 0x3f, 0x91, 0xdd, 0xbe, 0x84, 0x40, - 0x6b, 0x2f, 0x06, 0xa1, 0x43, 0x33, 0x77, 0x63, 0xf4, 0x2c, 0xc4, 0xe3, - 0x90, 0x62, 0xe5, 0x37, 0x99, 0xe9, 0x4d, 0xe0, 0x3d, 0xc6, 0x7c, 0x2a, - 0xae, 0x8c, 0x78, 0x61, 0x8f, 0xe2, 0x38, 0xdb, 0xb1, 0xb8, 0x61, 0x71, - 0xcf, 0xe2, 0x80, 0xe2, 0x9a, 0xc5, 0x1d, 0x8b, 0x3d, 0x8a, 0x2b, 0x16, - 0x37, 0x2c, 0xee, 0xd9, 0x26, 0x96, 0xd9, 0x6a, 0x8d, 0x68, 0xeb, 0xc0, - 0x87, 0xef, 0x2e, 0x2e, 0xdb, 0x6c, 0xcf, 0xbb, 0x34, 0xb2, 0x98, 0x03, - 0x59, 0x8b, 0x81, 0x38, 0xd6, 0xaa, 0x99, 0xdd, 0x51, 0x87, 0xf1, 0xa8, - 0xa5, 0xe1, 0x37, 0x04, 0xd6, 0x85, 0x14, 0x2b, 0x41, 0xbc, 0x95, 0x05, - 0x66, 0x24, 0x50, 0x87, 0x5a, 0x0b, 0x69, 0xe0, 0x5b, 0x62, 0x6c, 0x0f, - 0x51, 0xe8, 0x4b, 0x32, 0x7d, 0xe8, 0xcc, 0x24, 0x43, 0x12, 0x7d, 0x48, - 0xea, 0x5d, 0xd2, 0xe9, 0x27, 0x6e, 0x20, 0xee, 0x37, 0xdb, 0x67, 0x5f, - 0x93, 0xf4, 0x22, 0x1d, 0x49, 0x66, 0x85, 0x21, 0x19, 0xd6, 0x5b, 0x10, - 0x72, 0xe0, 0x7b, 0xb6, 0xbb, 0x73, 0x0b, 0xdd, 0x56, 0x79, 0xcb, 0x92, - 0xdf, 0x9d, 0x9f, 0x12, 0xbc, 0x8a, 0xb5, 0xe7, 0x3b, 0x81, 0x62, 0x60, - 0x95, 0x4e, 0xc2, 0x89, 0x01, 0x01, 0x26, 0x15, 0xc6, 0xec, 0x36, 0x7d, - 0xe8, 0x6d, 0xe9, 0xb0, 0x5b, 0xa3, 0xe3, 0xe7, 0x43, 0x66, 0x5d, 0x62, - 0x59, 0x27, 0xca, 0xdd, 0x89, 0x2d, 0x61, 0x94, 0x6f, 0x04, 0x9c, 0x6a, - 0x3a, 0x6a, 0x8e, 0xd3, 0x51, 0xb1, 0x9c, 0x8e, 0x7a, 0xe7, 0x80, 0xe5, - 0xe4, 0xaa, 0x43, 0xd2, 0x6a, 0x25, 0x16, 0xfe, 0x3d, 0x3f, 0xc4, 0xf4, - 0x26, 0xc5, 0xb9, 0x13, 0x31, 0x9c, 0x9d, 0xe8, 0x24, 0x55, 0xec, 0x0a, - 0x48, 0x4b, 0xc5, 0xfa, 0xa9, 0xd2, 0x53, 0xa5, 0xa7, 0x4a, 0xdf, 0x5e, - 0xe9, 0x97, 0x56, 0xd5, 0x9f, 0xaa, 0x3f, 0x55, 0xff, 0xd5, 0xab, 0xff, - 0x20, 0x75, 0xe5, 0x86, 0xd5, 0xa9, 0x6b, 0xeb, 0xe8, 0xd5, 0xd3, 0x43, - 0x6f, 0x0f, 0xe6, 0xa9, 0x86, 0x02, 0x49, 0xc7, 0xc3, 0x2b, 0x7a, 0x9c, - 0x8e, 0xb9, 0x17, 0x47, 0xf3, 0xd4, 0xd2, 0x65, 0xed, 0x77, 0x62, 0x2a, - 0xe3, 0x09, 0x45, 0x91, 0xa4, 0x6a, 0x24, 0xa5, 0x1a, 0xe9, 0x48, 0x79, - 0xe2, 0xba, 0x59, 0xca, 0xa3, 0xf8, 0x10, 0xe9, 0x30, 0x39, 0xcc, 0x93, - 0x03, 0xe5, 0x8a, 0xb7, 0x0e, 0x5f, 0xf5, 0x03, 0x35, 0x6b, 0x29, 0x9a, - 0x25, 0xe9, 0xd0, 0xf5, 0x3a, 0x34, 0x99, 0x27, 0x61, 0xc0, 0xe1, 0xc4, - 0x40, 0x07, 0x93, 0xc8, 0x92, 0x36, 0x92, 0x94, 0x97, 0xa4, 0xae, 0x40, - 0x0b, 0x9f, 0x5c, 0x92, 0xe2, 0x62, 0xed, 0xdf, 0x15, 0x57, 0xf1, 0x3c, - 0x30, 0x62, 0xab, 0x31, 0xc0, 0x0d, 0x35, 0xa2, 0x58, 0xbb, 0xa3, 0x38, - 0x85, 0x6f, 0x8c, 0x46, 0x25, 0x09, 0xf0, 0x4c, 0x9e, 0x9b, 0x60, 0xff, - 0x37, 0xc0, 0xf5, 0xf5, 0x73, 0xa9, 0x7b, 0x9d, 0x4b, 0xed, 0x75, 0xee, - 0xb9, 0xd9, 0xfe, 0xe0, 0x17, 0x18, 0x0c, 0x70, 0x6d, 0x82, 0xe0, 0x0c, - 0xbd, 0x91, 0x92, 0xdc, 0x0a, 0x78, 0xbd, 0xce, 0x3d, 0xf7, 0x3a, 0xf7, - 0x1c, 0x3a, 0x1d, 0x6a, 0xb7, 0x44, 0x44, 0xd7, 0x01, 0x13, 0x37, 0xd8, - 0xea, 0xce, 0xcf, 0x3d, 0x8f, 0xd0, 0xc9, 0x14, 0xc6, 0x8a, 0xe2, 0xed, - 0x50, 0x53, 0x1a, 0x76, 0x0d, 0xb5, 0x36, 0x77, 0xf5, 0xdc, 0xf3, 0xc9, - 0x51, 0xd2, 0x1f, 0x0d, 0x54, 0x05, 0x7b, 0xa4, 0xe9, 0x61, 0xc8, 0xbd, - 0xf5, 0xdc, 0xf3, 0x68, 0x16, 0x35, 0xa9, 0x75, 0xb4, 0x8e, 0xda, 0x73, - 0x11, 0x5e, 0x0d, 0x2d, 0xe2, 0x96, 0x73, 0xcf, 0x47, 0xab, 0x6d, 0x1d, - 0xf5, 0x50, 0x31, 0x50, 0x9b, 0xe7, 0x9e, 0xa3, 0xb3, 0x0d, 0xb4, 0x8e, - 0xf3, 0x73, 0xcf, 0x67, 0xab, 0xed, 0x80, 0xad, 0x23, 0x00, 0x73, 0x33, - 0x0d, 0x35, 0x77, 0x13, 0x6a, 0x9f, 0x9c, 0x7b, 0x6e, 0xfb, 0x71, 0x45, - 0x6d, 0xcc, 0xe1, 0x08, 0xc0, 0x5c, 0x8a, 0xb8, 0x71, 0xb4, 0x14, 0x9b, - 0x96, 0x62, 0xd5, 0x52, 0xcc, 0xb8, 0xb0, 0xda, 0xd7, 0x4e, 0xb2, 0x37, - 0xc4, 0x98, 0x6b, 0x22, 0xc6, 0x54, 0x20, 0x06, 0xf1, 0xab, 0x17, 0x7e, - 0x59, 0xed, 0x08, 0x4f, 0x96, 0x05, 0xd4, 0x3e, 0x9e, 0xab, 0x0f, 0xf3, - 0xc2, 0xdc, 0x12, 0xdb, 0xe7, 0x9e, 0xd8, 0x3e, 0x79, 0x62, 0xfb, 0x28, - 0x6c, 0x7f, 0x66, 0xb5, 0xeb, 0xb3, 0x53, 0xfe, 0x9b, 0x48, 0x09, 0xb0, - 0xf7, 0xec, 0x2b, 0x3d, 0x06, 0xd8, 0x73, 0xef, 0xcd, 0xda, 0x7b, 0xbf, - 0x4b, 0x0e, 0x29, 0xbe, 0x39, 0x40, 0x15, 0x58, 0x9f, 0x70, 0x44, 0x4c, - 0xb6, 0x33, 0x23, 0xc0, 0x08, 0x78, 0xd2, 0x60, 0xf9, 0xe9, 0x82, 0x6e, - 0xd7, 0xe1, 0xa9, 0xcb, 0x7e, 0xb0, 0xda, 0xae, 0xf8, 0x02, 0xc2, 0x3b, - 0x29, 0xe2, 0xbf, 0x49, 0xbf, 0xf5, 0xd2, 0x64, 0x13, 0xbd, 0x48, 0xba, - 0x7b, 0x90, 0xf6, 0x8a, 0xda, 0x22, 0x2d, 0x46, 0x6b, 0x46, 0x5d, 0x0c, - 0x00, 0x9c, 0x74, 0xd8, 0x64, 0x9b, 0x41, 0xed, 0x46, 0xb5, 0x5b, 0xd5, - 0x6e, 0x55, 0xbb, 0x53, 0xed, 0x9e, 0xb5, 0x23, 0x3c, 0xf9, 0x04, 0x51, - 0xbb, 0x52, 0x6d, 0x19, 0x01, 0x92, 0x3e, 0xef, 0x64, 0x0e, 0x48, 0x9a, - 0x7d, 0x84, 0x87, 0xda, 0x7d, 0x36, 0xc1, 0x27, 0x1b, 0x39, 0xa9, 0xa0, - 0x6a, 0xcb, 0x14, 0x91, 0x34, 0xfc, 0x08, 0x8f, 0x6a, 0x9c, 0x6a, 0xb7, - 0xaa, 0xdd, 0xa1, 0x36, 0x49, 0x11, 0x70, 0xca, 0xbe, 0xed, 0x9c, 0x90, - 0xd0, 0x97, 0x45, 0x1f, 0x2e, 0x15, 0x85, 0x43, 0xd1, 0x7c, 0xad, 0x48, - 0x74, 0x8a, 0x8f, 0xa0, 0xe8, 0x3d, 0xd3, 0x0b, 0x45, 0x6f, 0x98, 0x2e, - 0xb4, 0x8d, 0xce, 0x92, 0x55, 0xc3, 0xa5, 0xa2, 0xf6, 0x50, 0x44, 0xbe, - 0xba, 0x76, 0x65, 0xd1, 0xeb, 0x93, 0xa2, 0x45, 0x76, 0x0a, 0x2b, 0xb2, - 0x47, 0x6c, 0x1f, 0x2f, 0x87, 0xa2, 0x67, 0xdc, 0xf7, 0x20, 0x6b, 0xdc, - 0xe1, 0xa0, 0x83, 0xc7, 0xa2, 0xb6, 0x2c, 0x1a, 0x58, 0xb4, 0x1d, 0x8a, - 0x26, 0x16, 0x8d, 0xa9, 0x68, 0x26, 0xe5, 0x41, 0x91, 0xa3, 0xa1, 0xe0, - 0xce, 0xa2, 0x86, 0x45, 0x33, 0x39, 0xc0, 0xc8, 0xc5, 0xee, 0xef, 0x28, - 0xda, 0xa8, 0xda, 0xd7, 0x46, 0x5c, 0x8c, 0xbb, 0x5b, 0xd1, 0x74, 0x2c, - 0xea, 0x59, 0x14, 0x89, 0xed, 0x54, 0xb3, 0x68, 0xb9, 0x4f, 0x51, 0x1b, - 0x40, 0x71, 0x27, 0x7e, 0x68, 0x22, 0xe0, 0x83, 0x65, 0x3d, 0x0c, 0xe1, - 0x20, 0xc6, 0x20, 0xfd, 0x9b, 0xd1, 0xdf, 0xd5, 0xa8, 0x5e, 0x7c, 0xf5, - 0x23, 0xf2, 0x87, 0xd1, 0x28, 0xd4, 0xbe, 0xed, 0xcb, 0xa2, 0x9b, 0x5c, - 0x54, 0x1d, 0x8a, 0xba, 0xdb, 0x8b, 0xa2, 0xf5, 0x7e, 0x60, 0x91, 0x8f, - 0x44, 0x7a, 0xb1, 0xbf, 0x6e, 0x27, 0x3c, 0x56, 0x84, 0xe2, 0xa5, 0x28, - 0xea, 0xcb, 0xa2, 0xfa, 0xf6, 0xa2, 0x50, 0x14, 0x3d, 0x27, 0x7d, 0xb7, - 0xa2, 0x9d, 0x82, 0xba, 0xd6, 0x38, 0x13, 0x3e, 0x62, 0xa6, 0xcf, 0x25, - 0xed, 0x04, 0x3f, 0x16, 0x75, 0x56, 0x14, 0x7d, 0x75, 0xb5, 0xf9, 0x15, - 0xae, 0x14, 0x2d, 0x45, 0x51, 0x87, 0x8f, 0x9c, 0x58, 0xd1, 0x56, 0x95, - 0x45, 0x53, 0x87, 0xcf, 0xa3, 0xc5, 0x88, 0xf4, 0x80, 0x22, 0x63, 0x9b, - 0x63, 0x5b, 0x14, 0x6d, 0x87, 0xa2, 0xc9, 0x8a, 0xc6, 0x54, 0xb4, 0x57, - 0x5c, 0xeb, 0x54, 0xb4, 0x57, 0x1c, 0xfb, 0x4b, 0x45, 0x5d, 0x2a, 0xb2, - 0x0f, 0x46, 0xa1, 0xc8, 0xf0, 0x3e, 0x15, 0x8d, 0xa9, 0x68, 0xcb, 0x45, - 0x43, 0x83, 0x6f, 0xbc, 0x55, 0x51, 0xcc, 0xd9, 0xd9, 0xa1, 0x8a, 0xe6, - 0x43, 0x51, 0x9d, 0x8b, 0xda, 0x38, 0x15, 0x43, 0x43, 0xfe, 0xc3, 0xa2, - 0xc0, 0x6f, 0xcd, 0xa1, 0xc8, 0xbe, 0xfe, 0x66, 0x45, 0x91, 0x4d, 0xe7, - 0xa2, 0xbd, 0xd7, 0x17, 0x8b, 0xe2, 0x62, 0xe5, 0xa2, 0x17, 0xb9, 0xa8, - 0x61, 0x91, 0xbd, 0x8d, 0xb3, 0xb7, 0x82, 0xa2, 0x17, 0x2a, 0x8a, 0x72, - 0xc9, 0x42, 0x4a, 0xf3, 0xc2, 0x44, 0xe0, 0x97, 0x20, 0x42, 0xc7, 0xa2, - 0x97, 0x87, 0xa2, 0x50, 0x16, 0xdd, 0x58, 0xd1, 0x0d, 0xf8, 0xfa, 0x6a, - 0x45, 0x2b, 0x39, 0xf8, 0x8d, 0xd9, 0xfe, 0x52, 0xd1, 0x6a, 0x68, 0xbf, - 0x1d, 0x8a, 0x8c, 0x82, 0x7e, 0x3d, 0x14, 0xbd, 0xb3, 0xa2, 0x77, 0x65, - 0x51, 0x48, 0x45, 0x83, 0x18, 0x51, 0x05, 0x1e, 0xe3, 0x03, 0xd9, 0x3c, - 0x8d, 0xa9, 0xb7, 0x15, 0x8d, 0x65, 0xd1, 0x7a, 0xa9, 0x68, 0x3e, 0x14, - 0x39, 0x15, 0xd1, 0x18, 0xdd, 0x07, 0x0a, 0xd0, 0x32, 0xb2, 0xde, 0xb7, - 0x68, 0x71, 0xb2, 0x50, 0xcb, 0x5e, 0x8d, 0x8e, 0x1e, 0x8a, 0xc4, 0xd2, - 0xc0, 0xeb, 0x3a, 0x14, 0x35, 0x0f, 0x28, 0x1a, 0xad, 0x68, 0x4e, 0xbc, - 0xb0, 0x0a, 0x12, 0x47, 0x20, 0x61, 0x49, 0x02, 0xa1, 0x99, 0x93, 0x0c, - 0xf6, 0xbe, 0x45, 0xcb, 0xa1, 0x68, 0x38, 0x2d, 0xf2, 0xc9, 0xfe, 0x3e, - 0x24, 0xa5, 0xa5, 0x3a, 0x14, 0x75, 0x27, 0x45, 0xf3, 0xa1, 0xc8, 0xdd, - 0x5a, 0x54, 0x1f, 0x8a, 0xfa, 0x64, 0xb5, 0x77, 0x39, 0xee, 0xe8, 0x50, - 0xd4, 0x4a, 0xe5, 0x19, 0x21, 0xd6, 0x82, 0x5b, 0x8f, 0xb4, 0x57, 0x5b, - 0xba, 0x7a, 0x6a, 0x12, 0x7d, 0x99, 0x76, 0xe4, 0xb4, 0xc6, 0x05, 0x2f, - 0xa4, 0x7d, 0xe4, 0x58, 0xcb, 0x79, 0x2a, 0xed, 0xc5, 0x47, 0x2e, 0x73, - 0x9a, 0x1a, 0x93, 0x18, 0xeb, 0xb3, 0x34, 0x48, 0xe1, 0x30, 0x8e, 0x79, - 0x9a, 0x92, 0xb2, 0x93, 0xe2, 0xda, 0xb3, 0x4a, 0x51, 0xd7, 0x13, 0x96, - 0xa7, 0x9c, 0xad, 0xb6, 0xfa, 0x9c, 0x4a, 0xe4, 0xa7, 0xc2, 0x52, 0xa4, - 0x0b, 0x09, 0xd4, 0x52, 0x0a, 0x03, 0x45, 0x6a, 0x1b, 0x5d, 0x02, 0x49, - 0x91, 0x4e, 0x94, 0x61, 0x6c, 0x73, 0x26, 0xb9, 0x49, 0x92, 0x90, 0xe7, - 0x46, 0x52, 0x1a, 0xca, 0xd4, 0xa4, 0xcc, 0xe1, 0x42, 0xea, 0x33, 0xa2, - 0x5e, 0x4c, 0xfb, 0xec, 0xdc, 0x39, 0xa4, 0x12, 0x18, 0x4f, 0xd3, 0x36, - 0xa7, 0x4b, 0x99, 0x36, 0x39, 0x9d, 0x2f, 0xa5, 0x75, 0x4e, 0xa7, 0x32, - 0x6d, 0x72, 0x3a, 0x5e, 0x4a, 0xdb, 0x3b, 0xd2, 0x2e, 0xa7, 0x53, 0x99, - 0xf6, 0x39, 0x9d, 0x2f, 0xa5, 0x3e, 0x48, 0xfe, 0x3f, 0xa6, 0x21, 0xfb, - 0xc0, 0x4e, 0x53, 0xaa, 0xfc, 0x57, 0x53, 0xee, 0x98, 0xf3, 0x74, 0xa0, - 0xa9, 0xc6, 0xd2, 0x2d, 0xa7, 0x87, 0xbd, 0xb3, 0x5e, 0xdc, 0x3b, 0x5d, - 0x4a, 0x97, 0x8b, 0x7b, 0xa7, 0xcf, 0x7b, 0xa7, 0x7b, 0xc8, 0xde, 0x09, - 0x69, 0xef, 0x4c, 0x97, 0xf6, 0x4e, 0x95, 0xf7, 0xce, 0x61, 0x0f, 0xd5, - 0xdc, 0x37, 0xf5, 0x95, 0xbd, 0xd3, 0x24, 0xc9, 0x22, 0x5c, 0xdc, 0x3b, - 0xed, 0x31, 0x4d, 0x7b, 0xa6, 0x3b, 0xa6, 0x4b, 0x4e, 0xb1, 0x67, 0xfa, - 0x63, 0x8a, 0xcf, 0x63, 0x35, 0xb4, 0xb1, 0xe4, 0x14, 0xde, 0xbf, 0x62, - 0xef, 0x50, 0x2d, 0xc9, 0xac, 0x2b, 0xa5, 0xb3, 0xe1, 0x0a, 0x6d, 0x3d, - 0x0a, 0x52, 0x70, 0x81, 0x46, 0x9a, 0x8a, 0x6e, 0xe6, 0x58, 0xf7, 0x85, - 0x08, 0x28, 0x2c, 0xe1, 0x9d, 0x8c, 0x34, 0x3d, 0xbb, 0x19, 0xe7, 0xb8, - 0x27, 0x75, 0x9f, 0x64, 0x54, 0x19, 0xbd, 0x34, 0x91, 0x80, 0xe5, 0xdc, - 0x2a, 0xf2, 0x17, 0x5a, 0x57, 0xbc, 0xb9, 0xce, 0x07, 0xae, 0x04, 0x64, - 0x7d, 0x4c, 0x5b, 0x2d, 0xeb, 0x4a, 0xfc, 0xc7, 0x89, 0x58, 0x1d, 0x3d, - 0xd3, 0x0b, 0xac, 0x21, 0x11, 0x3a, 0xad, 0x21, 0xa3, 0xac, 0x21, 0x30, - 0x8b, 0xd0, 0x4e, 0x61, 0x7e, 0x41, 0xe4, 0xc2, 0x1a, 0x62, 0x92, 0xf3, - 0x0c, 0xdd, 0x28, 0x04, 0x98, 0x45, 0x2a, 0x14, 0x27, 0xab, 0xc9, 0xea, - 0xb8, 0x2e, 0x0b, 0xda, 0x85, 0x19, 0x63, 0x56, 0x73, 0x93, 0xd5, 0x94, - 0x0d, 0x67, 0x94, 0x0d, 0x67, 0x68, 0xc8, 0x7c, 0x61, 0x88, 0x68, 0xcc, - 0xfe, 0xb0, 0xa0, 0xfb, 0xc2, 0x65, 0x47, 0x0e, 0xba, 0xc2, 0xa2, 0xd4, - 0x5b, 0x04, 0x8c, 0x2b, 0x0c, 0x53, 0x9e, 0xf8, 0x8b, 0x39, 0x9c, 0x6d, - 0x05, 0x46, 0xad, 0xd6, 0x33, 0x2d, 0xc5, 0x73, 0x2d, 0x05, 0xa2, 0x1c, - 0xcc, 0xf5, 0x09, 0x26, 0x0f, 0xcd, 0xcf, 0x75, 0xdc, 0x3e, 0x30, 0xbb, - 0x8d, 0x76, 0xf1, 0x51, 0x04, 0xef, 0xb3, 0x0c, 0x07, 0x7f, 0x68, 0x4b, - 0xbf, 0xb3, 0xda, 0xc2, 0x0b, 0x20, 0xca, 0xe8, 0xf2, 0x6e, 0x75, 0x07, - 0x8d, 0x5f, 0x74, 0x30, 0x9c, 0xab, 0xfe, 0x23, 0x49, 0xc8, 0x51, 0xe3, - 0x17, 0xd1, 0x90, 0x64, 0x84, 0x16, 0x44, 0x06, 0x13, 0xdd, 0x3b, 0x57, - 0xd5, 0x37, 0x5d, 0x24, 0x9d, 0xfd, 0x44, 0x55, 0xf7, 0x6c, 0xd2, 0xa9, - 0x76, 0xa5, 0x4a, 0x72, 0xbb, 0x4b, 0x76, 0x28, 0xac, 0x9c, 0x22, 0x99, - 0xd4, 0x67, 0x9d, 0xb8, 0xbc, 0x4b, 0xac, 0x5d, 0x6e, 0x1e, 0x27, 0x96, - 0x9f, 0xbc, 0x40, 0x59, 0x16, 0x00, 0x2e, 0x11, 0x8c, 0x23, 0x98, 0xed, - 0x09, 0xcc, 0x3f, 0x07, 0x4c, 0xc4, 0xfc, 0x80, 0xf3, 0x0b, 0xec, 0x74, - 0xa4, 0x1f, 0x75, 0xe3, 0x92, 0x50, 0xda, 0x49, 0xe4, 0x9c, 0xac, 0xeb, - 0x59, 0xfe, 0xe4, 0x38, 0x28, 0x2c, 0x78, 0xdd, 0x0c, 0x69, 0x60, 0xad, - 0xa4, 0xa1, 0x25, 0xf5, 0x3f, 0xc1, 0xbc, 0xb3, 0x81, 0xe9, 0x5f, 0xb8, - 0x81, 0xf1, 0xe7, 0x35, 0x30, 0x7c, 0xbf, 0x06, 0xc2, 0xc3, 0x1a, 0x08, - 0x3f, 0xaf, 0x81, 0xed, 0xa1, 0x0d, 0xc0, 0x8b, 0x65, 0x47, 0x9a, 0x04, - 0xbc, 0x09, 0xfd, 0x43, 0x6f, 0x62, 0x2f, 0xf5, 0x19, 0x3d, 0x6a, 0x9a, - 0x85, 0x41, 0xb9, 0xe7, 0x85, 0xc4, 0x59, 0xd0, 0x80, 0xd4, 0x4b, 0x47, - 0x96, 0xb9, 0xf1, 0x51, 0x69, 0xc8, 0x81, 0xd6, 0x53, 0xc0, 0xf7, 0x76, - 0x31, 0xb2, 0x24, 0xa8, 0x64, 0x63, 0x9d, 0xa0, 0x17, 0xb2, 0x21, 0xa6, - 0xe0, 0xd9, 0xbd, 0x64, 0xf2, 0x90, 0x6d, 0xec, 0xc3, 0x7a, 0xe0, 0x66, - 0xc1, 0x24, 0x14, 0x9e, 0x44, 0xe6, 0x21, 0xc0, 0x8c, 0x15, 0xc4, 0x1a, - 0x9e, 0x71, 0x96, 0x64, 0x26, 0x1f, 0x70, 0x36, 0x59, 0x65, 0xa2, 0x2e, - 0x3c, 0x39, 0x43, 0x0b, 0x81, 0x67, 0x03, 0x86, 0xc2, 0xd3, 0x35, 0x65, - 0x59, 0x2c, 0x0a, 0x33, 0x9d, 0x44, 0x30, 0x3e, 0xb2, 0xea, 0x91, 0x59, - 0x8f, 0x8c, 0x7c, 0x84, 0x1e, 0xb4, 0xde, 0x5e, 0xf2, 0x1b, 0xed, 0x91, - 0x96, 0x82, 0xdc, 0xd8, 0xc3, 0x24, 0xc5, 0x93, 0xcc, 0x1e, 0xe9, 0x23, - 0xf8, 0xd5, 0x4c, 0xf5, 0xc1, 0x21, 0x3a, 0x93, 0x82, 0x6c, 0x15, 0x81, - 0x86, 0xa7, 0x90, 0x4c, 0x19, 0x0f, 0x7e, 0x24, 0x33, 0xa2, 0xc4, 0x7f, - 0xc4, 0x76, 0x12, 0xb7, 0xb9, 0xfb, 0x91, 0xef, 0xd3, 0x97, 0x87, 0x3c, - 0xe2, 0x7e, 0xfe, 0x1a, 0xfd, 0x7d, 0x8f, 0x5c, 0x42, 0xef, 0x3b, 0x76, - 0xc0, 0xc9, 0x3e, 0xe2, 0x56, 0x1b, 0x8e, 0x5b, 0x8d, 0xbb, 0x71, 0x39, - 0xee, 0xc6, 0x58, 0xdc, 0xc0, 0x1b, 0xb0, 0x82, 0x05, 0x68, 0x4f, 0x37, - 0xd0, 0x6d, 0x70, 0xee, 0x60, 0xad, 0x6d, 0xbf, 0x3f, 0x3f, 0xc5, 0xbf, - 0xb8, 0xff, 0x7f, 0x0f, 0x50, 0x33, 0xb1, 0x80, 0x24, 0x1e, 0x13, 0xd7, - 0x8f, 0xc6, 0x47, 0x3a, 0x3c, 0xb8, 0xb4, 0x3d, 0x4b, 0x9c, 0x4a, 0x12, - 0x95, 0xaa, 0x55, 0xd2, 0x08, 0x1d, 0x5a, 0x40, 0x63, 0x6d, 0xe7, 0x0a, - 0xd9, 0xbf, 0x0f, 0x24, 0x90, 0x9d, 0x84, 0xec, 0x4e, 0x58, 0x5b, 0x53, - 0x56, 0x72, 0x0c, 0xc4, 0x2e, 0x0d, 0x26, 0x06, 0xad, 0x21, 0xb4, 0x9a, - 0x0d, 0x3b, 0x35, 0x6c, 0x7d, 0x5b, 0x84, 0x75, 0x03, 0x7b, 0xa4, 0x70, - 0x86, 0xa0, 0xce, 0xcf, 0x69, 0x58, 0x69, 0xc0, 0x9a, 0x01, 0x6e, 0xdc, - 0x91, 0x13, 0x60, 0x01, 0x13, 0xb1, 0x67, 0x43, 0x0b, 0x0a, 0xaa, 0x83, - 0x22, 0xb9, 0x5c, 0x81, 0x7a, 0xb8, 0x74, 0x52, 0xb8, 0x7c, 0x65, 0x3c, - 0xd8, 0xe4, 0xf1, 0x1d, 0x4d, 0x93, 0x97, 0xe6, 0x6d, 0x7a, 0x1b, 0x9c, - 0x50, 0x53, 0x36, 0x3b, 0x20, 0xf6, 0xc0, 0x06, 0x33, 0x7a, 0xda, 0x2b, - 0x5a, 0x72, 0x01, 0xa9, 0x7c, 0x93, 0x0c, 0x5d, 0x98, 0x19, 0x81, 0x90, - 0xd6, 0x5f, 0x2b, 0x7c, 0xc1, 0x53, 0x79, 0x6e, 0x19, 0xbd, 0x50, 0x29, - 0xc0, 0xa1, 0xa7, 0x7a, 0xdd, 0x18, 0xb2, 0xda, 0x22, 0x0e, 0x1e, 0xc6, - 0x90, 0x99, 0xe1, 0x08, 0x65, 0x7f, 0x93, 0x1a, 0x84, 0x05, 0xf1, 0xa4, - 0x22, 0x2d, 0xd7, 0x25, 0xc9, 0xb9, 0xdd, 0xf5, 0x27, 0x83, 0x08, 0xd0, - 0x95, 0x27, 0xfb, 0xac, 0x62, 0x5d, 0x7e, 0xb2, 0x12, 0x55, 0xbb, 0xfa, - 0x64, 0xd1, 0x9d, 0x8b, 0x4f, 0x62, 0xd1, 0xd3, 0x47, 0x74, 0xd3, 0x0b, - 0x29, 0x4b, 0xc7, 0x0b, 0x91, 0xed, 0x09, 0x58, 0x90, 0xc9, 0xf7, 0x33, - 0xa6, 0x7a, 0xa9, 0xe4, 0x01, 0x20, 0x6e, 0x99, 0x8c, 0xfb, 0x4c, 0xdb, - 0xfd, 0x27, 0xf8, 0x6c, 0xec, 0xab, 0xc6, 0x7e, 0xe7, 0x93, 0x77, 0xcc, - 0xfc, 0x7d, 0x1a, 0x3b, 0x82, 0x48, 0xfd, 0x3d, 0xeb, 0x85, 0x18, 0x50, - 0x77, 0xbd, 0x60, 0xbb, 0x5c, 0xd0, 0x9f, 0x14, 0x54, 0xb9, 0x20, 0x39, - 0xd4, 0x07, 0x76, 0x77, 0x62, 0xcd, 0xe5, 0x22, 0xc8, 0xea, 0xf4, 0x81, - 0x3e, 0xd3, 0x97, 0x81, 0x0f, 0x8e, 0x7c, 0x10, 0x8b, 0xc8, 0xd4, 0x4e, - 0xdb, 0x89, 0xbf, 0x4f, 0x4c, 0x37, 0xae, 0xb2, 0x1d, 0xbf, 0x13, 0x7f, - 0x5f, 0xf4, 0x24, 0x11, 0xc5, 0xce, 0xe3, 0xf9, 0x46, 0x10, 0xd3, 0x3f, - 0xc9, 0xc2, 0x16, 0x2b, 0x34, 0xff, 0x60, 0x0b, 0xdb, 0xa7, 0x7f, 0xa2, - 0x85, 0xad, 0x13, 0xad, 0x24, 0xca, 0x2b, 0x3c, 0x31, 0xe8, 0x43, 0x4d, - 0xe9, 0x13, 0x5f, 0x89, 0x21, 0xdb, 0xf9, 0xed, 0xf6, 0x13, 0xab, 0xde, - 0xee, 0x03, 0xa6, 0xa0, 0x06, 0x7f, 0xbf, 0xf9, 0xe7, 0x47, 0x0d, 0x2a, - 0x81, 0xf9, 0x19, 0x83, 0x7a, 0xec, 0x60, 0xfe, 0x3f, 0xa1, 0xf4, 0x77, - 0x98, 0xe4, 0xf5, 0x00, 0x00 -}; +const uint8_t Antonio_SemiBold90pt7bBitmaps[] PROGMEM = { + 0x00, 0xFF, 0xFF, 0xFD, 0xFF, 0xFF, 0xF7, 0xFF, 0xFF, 0xDF, 0xFF, 0xFF, + 0x7F, 0xFF, 0xFD, 0xFF, 0xFF, 0xF7, 0xFF, 0xFF, 0xDF, 0xFF, 0xFF, 0x7F, + 0xFF, 0xFD, 0xFF, 0xFF, 0xF7, 0xFF, 0xFF, 0xDF, 0xFF, 0xFF, 0x7F, 0xFF, + 0xFD, 0xFF, 0xFF, 0xF7, 0xFF, 0xFF, 0xDF, 0xFF, 0xFF, 0x7F, 0xFF, 0xF8, + 0xFF, 0xFF, 0xE3, 0xFF, 0xFF, 0x8F, 0xFF, 0xFE, 0x3F, 0xFF, 0xF8, 0xFF, + 0xFF, 0xE3, 0xFF, 0xFF, 0x8F, 0xFF, 0xFE, 0x3F, 0xFF, 0xF8, 0xFF, 0xFF, + 0xE3, 0xFF, 0xFF, 0x8F, 0xFF, 0xFE, 0x3F, 0xFF, 0xF8, 0xFF, 0xFF, 0xE3, + 0xFF, 0xFF, 0x8F, 0xFF, 0xFE, 0x3F, 0xFF, 0xF8, 0xFF, 0xFF, 0xC1, 0xFF, + 0xFF, 0x07, 0xFF, 0xFC, 0x1F, 0xFF, 0xF0, 0x7F, 0xFF, 0xC1, 0xFF, 0xFF, + 0x07, 0xFF, 0xFC, 0x1F, 0xFF, 0xF0, 0x7F, 0xFF, 0xC1, 0xFF, 0xFF, 0x07, + 0xFF, 0xFC, 0x1F, 0xFF, 0xF0, 0x7F, 0xFF, 0xC1, 0xFF, 0xFF, 0x07, 0xFF, + 0xFC, 0x1F, 0xFF, 0xF0, 0x7F, 0xFF, 0xC0, 0xFF, 0xFE, 0x03, 0xFF, 0xF8, + 0x0F, 0xFF, 0xE0, 0x3F, 0xFF, 0x80, 0xFF, 0xFE, 0x03, 0xFF, 0xF8, 0x0F, + 0xFF, 0xE0, 0x3F, 0xFF, 0x80, 0xFF, 0xFE, 0x03, 0xFF, 0xF8, 0x0F, 0xFF, + 0xE0, 0x3F, 0xFF, 0x80, 0xFF, 0xFE, 0x03, 0xFF, 0xF8, 0x0F, 0xFF, 0xE0, + 0x3F, 0xFF, 0x80, 0xFF, 0xFE, 0x01, 0xFF, 0xF0, 0x07, 0xFF, 0xC0, 0x1F, + 0xFF, 0x00, 0x7F, 0xFC, 0x01, 0xFF, 0xF0, 0x07, 0xFF, 0xC0, 0x1F, 0xFF, + 0x00, 0x7F, 0xFC, 0x01, 0xFF, 0xF0, 0x07, 0xFF, 0xC0, 0x1F, 0xFF, 0x00, + 0x7F, 0xFC, 0x01, 0xFF, 0xF0, 0x07, 0xFF, 0xC0, 0x1F, 0xFF, 0x00, 0x7F, + 0xFC, 0x01, 0xFF, 0xF0, 0x03, 0xFF, 0x80, 0x0F, 0xFE, 0x00, 0x3F, 0xF8, + 0x00, 0xFF, 0xE0, 0x03, 0xFF, 0x80, 0x0F, 0xFE, 0x00, 0x3F, 0xF8, 0x00, + 0xFF, 0xE0, 0x03, 0xFF, 0x80, 0x0F, 0xFE, 0x00, 0x3F, 0xF8, 0x00, 0xFF, + 0xE0, 0x03, 0xFF, 0x80, 0x0F, 0xFE, 0x00, 0x3F, 0xF8, 0x00, 0xFF, 0xE0, + 0x03, 0xFF, 0x80, 0x07, 0xFC, 0x00, 0x1F, 0xF0, 0x00, 0x7F, 0xC0, 0x01, + 0xFF, 0x00, 0x07, 0xFC, 0x00, 0x1F, 0xF0, 0x00, 0x7F, 0xC0, 0x01, 0xFF, + 0x00, 0x07, 0xFC, 0x00, 0x1F, 0xF0, 0x00, 0x7F, 0xC0, 0x01, 0xFF, 0x00, + 0x07, 0xFC, 0x00, 0x1F, 0xF0, 0x00, 0x7F, 0xC0, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xFF, + 0xFF, 0xDF, 0xFF, 0xFF, 0x7F, 0xFF, 0xFD, 0xFF, 0xFF, 0xF7, 0xFF, 0xFF, + 0xDF, 0xFF, 0xFF, 0x7F, 0xFF, 0xFD, 0xFF, 0xFF, 0xF7, 0xFF, 0xFF, 0xDF, + 0xFF, 0xFF, 0x7F, 0xFF, 0xFD, 0xFF, 0xFF, 0xF7, 0xFF, 0xFF, 0xDF, 0xFF, + 0xFF, 0x7F, 0xFF, 0xFD, 0xFF, 0xFF, 0xF7, 0xFF, 0xFF, 0xDF, 0xFF, 0xFF, + 0x7F, 0xFF, 0xFD, 0xFF, 0xFF, 0xF7, 0xFF, 0xFF, 0xC0, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xBF, 0xFF, 0xFE, 0xFF, 0xFF, 0xF9, 0xFF, + 0xFF, 0xE7, 0xFF, 0xFF, 0x9F, 0xFF, 0xFE, 0x7F, 0xFF, 0xF9, 0xFF, 0xFF, + 0xC7, 0xFF, 0xFF, 0x1F, 0xFF, 0xFC, 0x7F, 0xFF, 0xF1, 0xFF, 0xFF, 0xC7, + 0xFF, 0xFF, 0x1F, 0xFF, 0xFC, 0x7F, 0xFF, 0xE1, 0xFF, 0xFF, 0x87, 0xFF, + 0xFE, 0x1F, 0xFF, 0xF8, 0x7F, 0xFF, 0xE1, 0xFF, 0xFF, 0x87, 0xFF, 0xFE, + 0x1F, 0xFF, 0xF0, 0x7F, 0xFF, 0xC1, 0xFF, 0xFF, 0x07, 0xFF, 0xFC, 0x1F, + 0xFF, 0xF0, 0x3F, 0xFF, 0xC0, 0xFF, 0xFF, 0x03, 0xFF, 0xF8, 0x0F, 0xFF, + 0xE0, 0x3F, 0xFF, 0x80, 0xFF, 0xFE, 0x03, 0xFF, 0xF8, 0x0F, 0xFF, 0xE0, + 0x3F, 0xFF, 0x80, 0xFF, 0xFC, 0x03, 0xFF, 0xF0, 0x0F, 0xFF, 0xC0, 0x3F, + 0xFF, 0x00, 0xFF, 0xFC, 0x03, 0xFF, 0xF0, 0x0F, 0xFF, 0xC0, 0x3F, 0xFE, + 0x00, 0xFF, 0xF8, 0x03, 0xFF, 0xE0, 0x0F, 0xFF, 0x80, 0x3F, 0xFE, 0x00, + 0xFF, 0xF8, 0x03, 0xFF, 0xE0, 0x07, 0xFF, 0x00, 0x1F, 0xFC, 0x00, 0x7F, + 0xF0, 0x01, 0xFF, 0xC0, 0x07, 0xFF, 0x00, 0x1F, 0xFC, 0x00, 0x7F, 0xF0, + 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xE0, 0x00, 0x3F, 0xFF, 0x80, 0x00, + 0x00, 0x00, 0x7F, 0xFF, 0x00, 0x01, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x03, + 0xFF, 0xF8, 0x00, 0x0F, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xC0, + 0x00, 0x7F, 0xFE, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFC, 0x00, 0x03, 0xFF, + 0xF0, 0x00, 0x00, 0x00, 0x07, 0xFF, 0xE0, 0x00, 0x3F, 0xFF, 0x80, 0x00, + 0x00, 0x00, 0x7F, 0xFF, 0x00, 0x01, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x03, + 0xFF, 0xF8, 0x00, 0x0F, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xC0, + 0x00, 0x7F, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFE, 0x00, 0x03, 0xFF, + 0xF8, 0x00, 0x00, 0x00, 0x07, 0xFF, 0xE0, 0x00, 0x1F, 0xFF, 0x80, 0x00, + 0x00, 0x00, 0x3F, 0xFF, 0x00, 0x01, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x03, + 0xFF, 0xF8, 0x00, 0x0F, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xC0, + 0x00, 0x7F, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFE, 0x00, 0x03, 0xFF, + 0xF8, 0x00, 0x00, 0x00, 0x07, 0xFF, 0xF0, 0x00, 0x1F, 0xFF, 0xC0, 0x00, + 0x00, 0x00, 0x3F, 0xFF, 0x00, 0x00, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x01, + 0xFF, 0xF8, 0x00, 0x0F, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xC0, + 0x00, 0x7F, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFE, 0x00, 0x03, 0xFF, + 0xF8, 0x00, 0x00, 0x00, 0x07, 0xFF, 0xF0, 0x00, 0x1F, 0xFF, 0xC0, 0x00, + 0x00, 0x00, 0x3F, 0xFF, 0x80, 0x00, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x01, + 0xFF, 0xF8, 0x00, 0x07, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xC0, + 0x00, 0x7F, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFE, 0x00, 0x03, 0xFF, + 0xF8, 0x00, 0x00, 0x00, 0x07, 0xFF, 0xF0, 0x00, 0x1F, 0xFF, 0xC0, 0x00, + 0x00, 0x00, 0x3F, 0xFF, 0x80, 0x00, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x01, + 0xFF, 0xFC, 0x00, 0x07, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xC0, + 0x00, 0x3F, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFE, 0x00, 0x03, 0xFF, + 0xF8, 0x00, 0x00, 0x00, 0x07, 0xFF, 0xF0, 0x00, 0x1F, 0xFF, 0xC0, 0x00, + 0x00, 0x00, 0x3F, 0xFF, 0x80, 0x00, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x01, + 0xFF, 0xFC, 0x00, 0x07, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xE0, + 0x00, 0x3F, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x7F, 0xFE, 0x00, 0x01, 0xFF, + 0xF8, 0x00, 0x00, 0x00, 0x03, 0xFF, 0xF0, 0x00, 0x1F, 0xFF, 0xC0, 0x00, + 0x00, 0x00, 0x3F, 0xFF, 0x80, 0x00, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x01, + 0xFF, 0xFC, 0x00, 0x07, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xE0, + 0x00, 0x3F, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0x00, 0x01, 0xFF, + 0xFC, 0x00, 0x00, 0x00, 0x03, 0xFF, 0xF0, 0x00, 0x0F, 0xFF, 0xC0, 0x00, + 0x00, 0x00, 0x1F, 0xFF, 0x80, 0x00, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x01, + 0xFF, 0xFC, 0x00, 0x07, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xE0, + 0x00, 0x3F, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0x00, 0x01, 0xFF, + 0xFC, 0x00, 0x00, 0x00, 0x03, 0xFF, 0xF8, 0x00, 0x0F, 0xFF, 0xE0, 0x00, + 0x00, 0x00, 0x1F, 0xFF, 0x80, 0x00, 0x7F, 0xFE, 0x00, 0x00, 0x00, 0x00, + 0xFF, 0xFC, 0x00, 0x07, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xE0, + 0x00, 0x3F, 0xFF, 0x80, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xC3, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, + 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x87, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xE1, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x7F, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC3, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xF0, 0x00, 0x03, 0xFF, 0xF8, 0x00, 0x0F, 0xFF, 0xE0, 0x00, + 0x00, 0x00, 0x1F, 0xFF, 0xC0, 0x00, 0x7F, 0xFF, 0x00, 0x00, 0x00, 0x00, + 0xFF, 0xFE, 0x00, 0x03, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x07, 0xFF, 0xF0, + 0x00, 0x1F, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0x00, 0x00, 0xFF, + 0xFC, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xF8, 0x00, 0x07, 0xFF, 0xE0, 0x00, + 0x00, 0x00, 0x1F, 0xFF, 0xC0, 0x00, 0x7F, 0xFF, 0x00, 0x00, 0x00, 0x00, + 0xFF, 0xFE, 0x00, 0x03, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x07, 0xFF, 0xF0, + 0x00, 0x1F, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0x80, 0x00, 0xFF, + 0xFE, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xF8, 0x00, 0x07, 0xFF, 0xE0, 0x00, + 0x00, 0x00, 0x0F, 0xFF, 0xC0, 0x00, 0x3F, 0xFF, 0x00, 0x00, 0x00, 0x00, + 0xFF, 0xFE, 0x00, 0x03, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x07, 0xFF, 0xF0, + 0x00, 0x1F, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0x80, 0x00, 0xFF, + 0xFE, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFC, 0x00, 0x07, 0xFF, 0xF0, 0x00, + 0x00, 0x00, 0x0F, 0xFF, 0xC0, 0x00, 0x3F, 0xFF, 0x00, 0x00, 0x00, 0x00, + 0x7F, 0xFE, 0x00, 0x01, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x03, 0xFF, 0xF0, + 0x00, 0x1F, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0x80, 0x00, 0xFF, + 0xFE, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFC, 0x00, 0x07, 0xFF, 0xF0, 0x00, + 0x00, 0x00, 0x0F, 0xFF, 0xE0, 0x00, 0x3F, 0xFF, 0x80, 0x00, 0x00, 0x00, + 0x7F, 0xFE, 0x00, 0x01, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x03, 0xFF, 0xF0, + 0x00, 0x0F, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0x80, 0x00, 0x7F, + 0xFE, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFC, 0x00, 0x07, 0xFF, 0xF0, 0x00, + 0x00, 0x00, 0x0F, 0xFF, 0xE0, 0x00, 0x3F, 0xFF, 0x80, 0x00, 0x00, 0x00, + 0x7F, 0xFF, 0x00, 0x01, 0xFF, 0xFC, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x87, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFC, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xE1, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0F, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x7F, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC3, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFE, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xF0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x87, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x3F, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0x00, 0x1F, 0xFF, 0xC0, 0x00, 0x7F, + 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFE, 0x00, 0x03, 0xFF, 0xF8, 0x00, + 0x00, 0x00, 0x07, 0xFF, 0xE0, 0x00, 0x1F, 0xFF, 0x80, 0x00, 0x00, 0x00, + 0x3F, 0xFF, 0x00, 0x01, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x03, 0xFF, 0xF8, + 0x00, 0x0F, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xC0, 0x00, 0x7F, + 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFE, 0x00, 0x03, 0xFF, 0xF8, 0x00, + 0x00, 0x00, 0x07, 0xFF, 0xF0, 0x00, 0x1F, 0xFF, 0xC0, 0x00, 0x00, 0x00, + 0x3F, 0xFF, 0x00, 0x00, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xF8, + 0x00, 0x0F, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xC0, 0x00, 0x7F, + 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFE, 0x00, 0x03, 0xFF, 0xF8, 0x00, + 0x00, 0x00, 0x07, 0xFF, 0xF0, 0x00, 0x1F, 0xFF, 0xC0, 0x00, 0x00, 0x00, + 0x3F, 0xFF, 0x80, 0x00, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFC, + 0x00, 0x07, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xC0, 0x00, 0x3F, + 0xFF, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFE, 0x00, 0x03, 0xFF, 0xF8, 0x00, + 0x00, 0x00, 0x07, 0xFF, 0xF0, 0x00, 0x1F, 0xFF, 0xC0, 0x00, 0x00, 0x00, + 0x3F, 0xFF, 0x80, 0x00, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFC, + 0x00, 0x07, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xE0, 0x00, 0x3F, + 0xFF, 0x80, 0x00, 0x00, 0x00, 0x7F, 0xFE, 0x00, 0x01, 0xFF, 0xF8, 0x00, + 0x00, 0x00, 0x03, 0xFF, 0xF0, 0x00, 0x1F, 0xFF, 0xC0, 0x00, 0x00, 0x00, + 0x3F, 0xFF, 0x80, 0x00, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFC, + 0x00, 0x07, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xE0, 0x00, 0x3F, + 0xFF, 0x80, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0x00, 0x01, 0xFF, 0xFC, 0x00, + 0x00, 0x00, 0x03, 0xFF, 0xF0, 0x00, 0x0F, 0xFF, 0xC0, 0x00, 0x00, 0x00, + 0x1F, 0xFF, 0x80, 0x00, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFC, + 0x00, 0x07, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xE0, 0x00, 0x3F, + 0xFF, 0x80, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0x00, 0x01, 0xFF, 0xFC, 0x00, + 0x00, 0x00, 0x03, 0xFF, 0xF8, 0x00, 0x0F, 0xFF, 0xE0, 0x00, 0x00, 0x00, + 0x1F, 0xFF, 0xC0, 0x00, 0x7F, 0xFE, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFC, + 0x00, 0x07, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xE0, 0x00, 0x3F, + 0xFF, 0x80, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0x00, 0x01, 0xFF, 0xFC, 0x00, + 0x00, 0x00, 0x03, 0xFF, 0xF8, 0x00, 0x0F, 0xFF, 0xE0, 0x00, 0x00, 0x00, + 0x1F, 0xFF, 0xC0, 0x00, 0x7F, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFE, + 0x00, 0x03, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x07, 0xFF, 0xE0, 0x00, 0x1F, + 0xFF, 0x80, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0x00, 0x01, 0xFF, 0xFC, 0x00, + 0x00, 0x00, 0x03, 0xFF, 0xF8, 0x00, 0x0F, 0xFF, 0xE0, 0x00, 0x00, 0x00, + 0x1F, 0xFF, 0xC0, 0x00, 0x7F, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFE, + 0x00, 0x03, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x07, 0xFF, 0xF0, 0x00, 0x1F, + 0xFF, 0x80, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0x00, 0x00, 0xFF, 0xFC, 0x00, + 0x00, 0x00, 0x01, 0xFF, 0xF8, 0x00, 0x0F, 0xFF, 0xE0, 0x00, 0x00, 0x00, + 0x1F, 0xFF, 0xC0, 0x00, 0x7F, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFE, + 0x00, 0x03, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x07, 0xFF, 0xF0, 0x00, 0x1F, + 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0x80, 0x00, 0xFF, 0xFE, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xE0, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x0F, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xFF, 0x80, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x3F, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, + 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xC0, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x1F, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xFF, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x0F, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xFF, 0x80, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x3F, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xFE, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x1F, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xFF, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x7F, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, + 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xFF, 0x80, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xE0, + 0x00, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x01, 0xFF, + 0xFF, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xE0, 0x00, + 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xFE, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, + 0xFF, 0xE0, 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x00, 0x00, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, + 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x01, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFC, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x0F, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x1F, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFE, 0x03, 0xFF, 0xFF, 0xF8, 0x07, 0xFF, 0xFF, 0xC0, + 0x7F, 0xFF, 0xFC, 0x00, 0x7F, 0xFF, 0xFC, 0x1F, 0xFF, 0xFF, 0x00, 0x07, + 0xFF, 0xFF, 0x83, 0xFF, 0xFF, 0xC0, 0x00, 0x7F, 0xFF, 0xF0, 0x7F, 0xFF, + 0xF8, 0x00, 0x0F, 0xFF, 0xFE, 0x0F, 0xFF, 0xFE, 0x00, 0x00, 0xFF, 0xFF, + 0xC1, 0xFF, 0xFF, 0xC0, 0x00, 0x1F, 0xFF, 0xFC, 0x3F, 0xFF, 0xF8, 0x00, + 0x03, 0xFF, 0xFF, 0x87, 0xFF, 0xFF, 0x00, 0x00, 0x3F, 0xFF, 0xF1, 0xFF, + 0xFF, 0xE0, 0x00, 0x07, 0xFF, 0xFE, 0x3F, 0xFF, 0xF8, 0x00, 0x00, 0xFF, + 0xFF, 0xC7, 0xFF, 0xFF, 0x00, 0x00, 0x1F, 0xFF, 0xF8, 0xFF, 0xFF, 0xE0, + 0x00, 0x03, 0xFF, 0xFF, 0x1F, 0xFF, 0xFC, 0x00, 0x00, 0x7F, 0xFF, 0xF3, + 0xFF, 0xFF, 0x80, 0x00, 0x0F, 0xFF, 0xFE, 0x7F, 0xFF, 0xF0, 0x00, 0x01, + 0xFF, 0xFF, 0xCF, 0xFF, 0xFF, 0x00, 0x00, 0x1F, 0xFF, 0xF9, 0xFF, 0xFF, + 0xE0, 0x00, 0x03, 0xFF, 0xFF, 0x1F, 0xFF, 0xFC, 0x00, 0x00, 0x7F, 0xFF, + 0xE3, 0xFF, 0xFF, 0x80, 0x00, 0x0F, 0xFF, 0xFC, 0x7F, 0xFF, 0xF0, 0x00, + 0x01, 0xFF, 0xFF, 0x8F, 0xFF, 0xFF, 0x00, 0x00, 0x3F, 0xFF, 0xF1, 0xFF, + 0xFF, 0xE0, 0x00, 0x07, 0xFF, 0xFE, 0x3F, 0xFF, 0xFC, 0x00, 0x00, 0xFF, + 0xFF, 0xC3, 0xFF, 0xFF, 0xC0, 0x00, 0x1F, 0xFF, 0xF8, 0x7F, 0xFF, 0xF8, + 0x00, 0x03, 0xFF, 0xFF, 0x0F, 0xFF, 0xFF, 0x80, 0x00, 0x7F, 0xFF, 0xE1, + 0xFF, 0xFF, 0xF0, 0x00, 0x0F, 0xFF, 0xFC, 0x1F, 0xFF, 0xFF, 0x00, 0x01, + 0xFF, 0xFF, 0x83, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, + 0xFF, 0x00, 0x00, 0x00, 0x00, 0x07, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x00, + 0x00, 0xFF, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xE0, + 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x1F, + 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xFE, 0x00, 0x00, + 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x03, 0xFF, 0xFF, + 0xFF, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, + 0x07, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xF0, + 0x00, 0x00, 0x00, 0x07, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x7F, + 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0x00, 0x00, + 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFF, + 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, + 0x0F, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xF0, + 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x7F, + 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x07, 0xFF, 0xFF, 0xFF, 0x00, 0x00, + 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x07, 0xFF, 0xFF, + 0xFE, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x00, + 0x07, 0xFF, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xC0, + 0x00, 0x00, 0x00, 0x07, 0xFF, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x7F, + 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x07, 0xFF, 0xFF, 0xF8, 0x00, 0x00, + 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x07, 0xFF, 0xFF, + 0xF0, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, + 0x07, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFE, 0x00, + 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00, 0xFF, + 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xFF, 0x8F, 0xFF, 0xFE, + 0x00, 0x01, 0xFF, 0xFF, 0xF1, 0xFF, 0xFF, 0xC0, 0x00, 0x3F, 0xFF, 0xFE, + 0x3F, 0xFF, 0xF8, 0x00, 0x03, 0xFF, 0xFF, 0xE7, 0xFF, 0xFF, 0x00, 0x00, + 0x7F, 0xFF, 0xFC, 0xFF, 0xFF, 0xE0, 0x00, 0x0F, 0xFF, 0xFF, 0x9F, 0xFF, + 0xFC, 0x00, 0x00, 0xFF, 0xFF, 0xF3, 0xFF, 0xFF, 0x80, 0x00, 0x1F, 0xFF, + 0xFE, 0x7F, 0xFF, 0xF0, 0x00, 0x03, 0xFF, 0xFF, 0xEF, 0xFF, 0xFE, 0x00, + 0x00, 0x3F, 0xFF, 0xFD, 0xFF, 0xFF, 0xC0, 0x00, 0x07, 0xFF, 0xFF, 0xBF, + 0xFF, 0xF8, 0x00, 0x00, 0xFF, 0xFF, 0xF7, 0xFF, 0xFF, 0x00, 0x00, 0x1F, + 0xFF, 0xFE, 0xFF, 0xFF, 0xE0, 0x00, 0x03, 0xFF, 0xFF, 0xDF, 0xFF, 0xFC, + 0x00, 0x00, 0x7F, 0xFF, 0xFB, 0xFF, 0xFF, 0x80, 0x00, 0x0F, 0xFF, 0xFF, + 0x7F, 0xFF, 0xF0, 0x00, 0x01, 0xFF, 0xFF, 0xEF, 0xFF, 0xFE, 0x00, 0x00, + 0x3F, 0xFF, 0xFD, 0xFF, 0xFF, 0xC0, 0x00, 0x07, 0xFF, 0xFF, 0x9F, 0xFF, + 0xFC, 0x00, 0x00, 0xFF, 0xFF, 0xF3, 0xFF, 0xFF, 0x80, 0x00, 0x1F, 0xFF, + 0xFE, 0x7F, 0xFF, 0xF0, 0x00, 0x03, 0xFF, 0xFF, 0xCF, 0xFF, 0xFE, 0x00, + 0x00, 0x7F, 0xFF, 0xF9, 0xFF, 0xFF, 0xC0, 0x00, 0x0F, 0xFF, 0xFF, 0x3F, + 0xFF, 0xFC, 0x00, 0x03, 0xFF, 0xFF, 0xC3, 0xFF, 0xFF, 0x80, 0x00, 0x7F, + 0xFF, 0xF8, 0x7F, 0xFF, 0xF8, 0x00, 0x0F, 0xFF, 0xFF, 0x0F, 0xFF, 0xFF, + 0x00, 0x03, 0xFF, 0xFF, 0xE1, 0xFF, 0xFF, 0xF0, 0x00, 0xFF, 0xFF, 0xF8, + 0x1F, 0xFF, 0xFF, 0x00, 0x3F, 0xFF, 0xFF, 0x03, 0xFF, 0xFF, 0xF8, 0x3F, + 0xFF, 0xFF, 0xE0, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x07, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xE0, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x01, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0x00, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x03, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFE, 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x3F, 0xFF, + 0xFF, 0xFF, 0xFF, 0xE0, 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x00, + 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0xFF, + 0xFF, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00, + 0x7F, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0x80, 0x00, + 0x00, 0x00, 0x00, 0x01, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, + 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xFE, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0xF8, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x03, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x7F, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFC, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x01, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xF0, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0xF8, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x03, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, + 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFC, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x01, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xF0, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x07, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xF8, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, + 0xFF, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0xFF, + 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xE0, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xFF, 0xF8, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x03, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, + 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, + 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, + 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xC0, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, + 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xFF, 0xFC, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x3F, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xE0, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x07, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0xFF, 0xFF, 0xFE, 0x7F, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, + 0x03, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xF0, + 0x01, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xF8, 0x00, 0x1F, 0xFF, 0xF8, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x0F, 0xFF, 0xFC, 0x00, 0x03, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x1F, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xFF, 0xFE, + 0x00, 0x00, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x07, 0xFF, 0xF8, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0x80, 0x00, 0x1F, 0xFF, + 0xF0, 0x00, 0x00, 0x00, 0x00, 0x03, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x7F, 0xFF, 0xC0, 0x00, 0x07, 0xFF, 0xFC, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0xFF, + 0xF0, 0x00, 0x01, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, + 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xFF, 0xFC, 0x00, 0x00, 0x7F, + 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xE0, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x01, 0xFF, 0xFF, 0x00, 0x00, 0x0F, 0xFF, 0xF8, 0x00, 0x00, + 0x00, 0x00, 0x07, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, + 0xFF, 0xC0, 0x00, 0x03, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x03, 0xFF, + 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xF0, 0x00, 0x00, + 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xF8, 0x00, 0x00, 0x3F, 0xFF, 0xE0, 0x00, + 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, + 0xFF, 0xFE, 0x00, 0x00, 0x0F, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x1F, + 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x80, 0x00, + 0x03, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x07, 0xFF, 0xF8, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xE0, 0x00, 0x00, 0xFF, 0xFF, 0x80, + 0x00, 0x00, 0x00, 0x03, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x0F, 0xFF, 0xF8, 0x00, 0x00, 0x3F, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x00, + 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xFF, 0xFE, 0x00, + 0x00, 0x0F, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xC0, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x80, 0x00, 0x03, 0xFF, 0xFE, + 0x00, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x3F, 0xFF, 0xE0, 0x00, 0x00, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00, + 0x07, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xF8, + 0x00, 0x00, 0x3F, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFE, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xFF, 0xFE, 0x00, 0x00, 0x0F, 0xFF, + 0xF8, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xFF, 0xFF, 0x80, 0x00, 0x03, 0xFF, 0xFE, 0x00, 0x00, 0x00, + 0x00, 0x3F, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, + 0xE0, 0x00, 0x00, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xE0, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xF8, 0x00, 0x00, 0x3F, + 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x07, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x03, 0xFF, 0xFE, 0x00, 0x00, 0x0F, 0xFF, 0xF8, 0x00, 0x00, + 0x00, 0x01, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, + 0xFF, 0x80, 0x00, 0x03, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xE0, 0x00, 0x00, + 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xC0, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xF8, 0x00, 0x00, 0x3F, 0xFF, 0xE0, 0x00, + 0x00, 0x00, 0x1F, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, + 0xFF, 0xFE, 0x00, 0x00, 0x0F, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x07, 0xFF, + 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x80, 0x00, + 0x03, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFE, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xE0, 0x00, 0x00, 0xFF, 0xFF, 0x80, + 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x0F, 0xFF, 0xF8, 0x00, 0x00, 0x3F, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x3F, + 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xFF, 0xFE, 0x00, + 0x00, 0x0F, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xE0, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x80, 0x00, 0x03, 0xFF, 0xFE, + 0x00, 0x00, 0x00, 0x07, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x3F, 0xFF, 0xE0, 0x00, 0x00, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x01, + 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xF8, + 0x00, 0x00, 0x3F, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xFF, 0xFE, 0x00, 0x00, 0x0F, 0xFF, + 0xF8, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x7E, 0x00, + 0x00, 0x00, 0xFF, 0xFF, 0x80, 0x00, 0x03, 0xFF, 0xFE, 0x00, 0x00, 0x00, + 0x1F, 0xFF, 0xE0, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0x80, 0x00, 0x3F, 0xFF, + 0xE0, 0x00, 0x00, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x07, 0xFF, 0xF8, 0x00, + 0x00, 0x1F, 0xFF, 0xFF, 0xFC, 0x00, 0x0F, 0xFF, 0xF8, 0x00, 0x00, 0x3F, + 0xFF, 0xE0, 0x00, 0x00, 0x01, 0xFF, 0xFE, 0x00, 0x00, 0x1F, 0xFF, 0xFF, + 0xFF, 0xC0, 0x03, 0xFF, 0xFE, 0x00, 0x00, 0x0F, 0xFF, 0xF8, 0x00, 0x00, + 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x1F, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0xFF, + 0xFF, 0x80, 0x00, 0x03, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xC0, + 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x3F, 0xFF, 0xE0, 0x00, 0x00, + 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x1F, 0xFF, 0xF0, 0x00, 0x07, 0xFF, 0xFF, + 0xFF, 0xFF, 0xF0, 0x0F, 0xFF, 0xF8, 0x00, 0x00, 0x3F, 0xFF, 0xE0, 0x00, + 0x00, 0x07, 0xFF, 0xF8, 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x03, + 0xFF, 0xFE, 0x00, 0x00, 0x0F, 0xFF, 0xF8, 0x00, 0x00, 0x01, 0xFF, 0xFE, + 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0xFF, 0xFF, 0x80, 0x00, + 0x03, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xF8, 0x3F, 0xFF, 0xE0, 0x00, 0x00, 0xFF, 0xFF, 0x80, + 0x00, 0x00, 0x3F, 0xFF, 0xC0, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, + 0x0F, 0xFF, 0xF8, 0x00, 0x00, 0x3F, 0xFF, 0xE0, 0x00, 0x00, 0x1F, 0xFF, + 0xF0, 0x00, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC3, 0xFF, 0xFE, 0x00, + 0x00, 0x0F, 0xFF, 0xF8, 0x00, 0x00, 0x07, 0xFF, 0xF8, 0x00, 0x0F, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0xFF, 0xFF, 0x80, 0x00, 0x03, 0xFF, 0xFE, + 0x00, 0x00, 0x01, 0xFF, 0xFE, 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFE, 0x3F, 0xFF, 0xE0, 0x00, 0x00, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0xFF, + 0xFF, 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x8F, 0xFF, 0xF8, + 0x00, 0x00, 0x3F, 0xFF, 0xE0, 0x00, 0x00, 0x3F, 0xFF, 0xC0, 0x00, 0x7F, + 0xFF, 0xFE, 0x03, 0xFF, 0xFF, 0xE3, 0xFF, 0xFE, 0x00, 0x00, 0x0F, 0xFF, + 0xF8, 0x00, 0x00, 0x1F, 0xFF, 0xF0, 0x00, 0x1F, 0xFF, 0xFC, 0x00, 0x3F, + 0xFF, 0xFC, 0xFF, 0xFF, 0x80, 0x00, 0x03, 0xFF, 0xFE, 0x00, 0x00, 0x07, + 0xFF, 0xF8, 0x00, 0x07, 0xFF, 0xFE, 0x00, 0x03, 0xFF, 0xFF, 0x3F, 0xFF, + 0xE0, 0x00, 0x00, 0xFF, 0xFF, 0x80, 0x00, 0x01, 0xFF, 0xFE, 0x00, 0x03, + 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xCF, 0xFF, 0xF8, 0x00, 0x00, 0x3F, + 0xFF, 0xE0, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xC0, 0x00, + 0x1F, 0xFF, 0xF3, 0xFF, 0xFE, 0x00, 0x00, 0x0F, 0xFF, 0xF8, 0x00, 0x00, + 0x3F, 0xFF, 0xC0, 0x00, 0x3F, 0xFF, 0xE0, 0x00, 0x07, 0xFF, 0xFE, 0xFF, + 0xFF, 0x80, 0x00, 0x03, 0xFF, 0xFE, 0x00, 0x00, 0x1F, 0xFF, 0xF0, 0x00, + 0x0F, 0xFF, 0xF8, 0x00, 0x00, 0xFF, 0xFF, 0xBF, 0xFF, 0xE0, 0x00, 0x00, + 0xFF, 0xFF, 0x80, 0x00, 0x07, 0xFF, 0xF8, 0x00, 0x07, 0xFF, 0xFE, 0x00, + 0x00, 0x3F, 0xFF, 0xEF, 0xFF, 0xF8, 0x00, 0x00, 0x3F, 0xFF, 0xE0, 0x00, + 0x01, 0xFF, 0xFE, 0x00, 0x01, 0xFF, 0xFF, 0x00, 0x00, 0x0F, 0xFF, 0xFB, + 0xFF, 0xFE, 0x00, 0x00, 0x0F, 0xFF, 0xF8, 0x00, 0x00, 0xFF, 0xFF, 0x00, + 0x00, 0x7F, 0xFF, 0xC0, 0x00, 0x03, 0xFF, 0xFE, 0xFF, 0xFF, 0xC0, 0x00, + 0x03, 0xFF, 0xFE, 0x00, 0x00, 0x3F, 0xFF, 0xC0, 0x00, 0x1F, 0xFF, 0xF0, + 0x00, 0x00, 0xFF, 0xFF, 0x9F, 0xFF, 0xF0, 0x00, 0x00, 0xFF, 0xFF, 0x80, + 0x00, 0x1F, 0xFF, 0xF0, 0x00, 0x07, 0xFF, 0xFC, 0x00, 0x00, 0x3F, 0xFF, + 0xE7, 0xFF, 0xFC, 0x00, 0x00, 0x3F, 0xFF, 0xE0, 0x00, 0x07, 0xFF, 0xF8, + 0x00, 0x01, 0xFF, 0xFF, 0x00, 0x00, 0x0F, 0xFF, 0xFD, 0xFF, 0xFF, 0x00, + 0x00, 0x1F, 0xFF, 0xF8, 0x00, 0x01, 0xFF, 0xFE, 0x00, 0x00, 0x7F, 0xFF, + 0xC0, 0x00, 0x01, 0xFF, 0xFF, 0x7F, 0xFF, 0xC0, 0x00, 0x07, 0xFF, 0xFC, + 0x00, 0x00, 0xFF, 0xFF, 0x80, 0x00, 0x1F, 0xFF, 0xF0, 0x00, 0x00, 0x7F, + 0xFF, 0xDF, 0xFF, 0xF0, 0x00, 0x01, 0xFF, 0xFF, 0x00, 0x00, 0x3F, 0xFF, + 0xC0, 0x00, 0x07, 0xFF, 0xFC, 0x00, 0x00, 0x1F, 0xFF, 0xF7, 0xFF, 0xFE, + 0x00, 0x00, 0x7F, 0xFF, 0xC0, 0x00, 0x1F, 0xFF, 0xF0, 0x00, 0x01, 0xFF, + 0xFF, 0x00, 0x00, 0x07, 0xFF, 0xFC, 0xFF, 0xFF, 0x80, 0x00, 0x3F, 0xFF, + 0xF0, 0x00, 0x07, 0xFF, 0xF8, 0x00, 0x00, 0x7F, 0xFF, 0xC0, 0x00, 0x01, + 0xFF, 0xFF, 0x3F, 0xFF, 0xF0, 0x00, 0x0F, 0xFF, 0xFC, 0x00, 0x01, 0xFF, + 0xFE, 0x00, 0x00, 0x1F, 0xFF, 0xF0, 0x00, 0x00, 0x7F, 0xFF, 0xCF, 0xFF, + 0xFC, 0x00, 0x07, 0xFF, 0xFE, 0x00, 0x00, 0xFF, 0xFF, 0x80, 0x00, 0x07, + 0xFF, 0xFC, 0x00, 0x00, 0x1F, 0xFF, 0xF3, 0xFF, 0xFF, 0x80, 0x03, 0xFF, + 0xFF, 0x80, 0x00, 0x3F, 0xFF, 0xC0, 0x00, 0x01, 0xFF, 0xFF, 0x00, 0x00, + 0x07, 0xFF, 0xFC, 0x7F, 0xFF, 0xF8, 0x03, 0xFF, 0xFF, 0xE0, 0x00, 0x1F, + 0xFF, 0xF0, 0x00, 0x00, 0x7F, 0xFF, 0xC0, 0x00, 0x01, 0xFF, 0xFF, 0x1F, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x07, 0xFF, 0xF8, 0x00, 0x00, + 0x1F, 0xFF, 0xF0, 0x00, 0x00, 0x7F, 0xFF, 0xC7, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFC, 0x00, 0x01, 0xFF, 0xFE, 0x00, 0x00, 0x07, 0xFF, 0xFC, 0x00, + 0x00, 0x1F, 0xFF, 0xF0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x00, 0x00, + 0xFF, 0xFF, 0x80, 0x00, 0x01, 0xFF, 0xFF, 0x00, 0x00, 0x07, 0xFF, 0xFC, + 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x3F, 0xFF, 0xC0, 0x00, + 0x00, 0x7F, 0xFF, 0xC0, 0x00, 0x01, 0xFF, 0xFF, 0x07, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xC0, 0x00, 0x1F, 0xFF, 0xF0, 0x00, 0x00, 0x1F, 0xFF, 0xF0, + 0x00, 0x00, 0x7F, 0xFF, 0xC0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, + 0x07, 0xFF, 0xF8, 0x00, 0x00, 0x07, 0xFF, 0xFC, 0x00, 0x00, 0x1F, 0xFF, + 0xF0, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x00, 0x01, 0xFF, 0xFE, 0x00, + 0x00, 0x01, 0xFF, 0xFF, 0x00, 0x00, 0x07, 0xFF, 0xFC, 0x07, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFC, 0x00, 0x00, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x7F, 0xFF, + 0xC0, 0x00, 0x01, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x00, + 0x00, 0x3F, 0xFF, 0xC0, 0x00, 0x00, 0x1F, 0xFF, 0xF0, 0x00, 0x00, 0x7F, + 0xFF, 0xC0, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x1F, 0xFF, 0xF0, + 0x00, 0x00, 0x07, 0xFF, 0xFC, 0x00, 0x00, 0x1F, 0xFF, 0xF0, 0x03, 0xFF, + 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x07, 0xFF, 0xF8, 0x00, 0x00, 0x01, 0xFF, + 0xFF, 0x00, 0x00, 0x07, 0xFF, 0xFC, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xC0, + 0x00, 0x01, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xC0, 0x00, 0x01, + 0xFF, 0xFF, 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0xFF, 0xFF, + 0x80, 0x00, 0x00, 0x1F, 0xFF, 0xF0, 0x00, 0x00, 0x7F, 0xFF, 0xC0, 0x00, + 0x3F, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x3F, 0xFF, 0xC0, 0x00, 0x00, 0x07, + 0xFF, 0xFC, 0x00, 0x00, 0x1F, 0xFF, 0xF0, 0x00, 0x00, 0x7F, 0xFC, 0x00, + 0x00, 0x00, 0x1F, 0xFF, 0xF0, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0x00, 0x00, + 0x07, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xFF, + 0xF8, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xC0, 0x00, 0x01, 0xFF, 0xFF, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFE, 0x00, 0x00, 0x00, + 0x1F, 0xFF, 0xF0, 0x00, 0x00, 0x7F, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x07, 0xFF, 0xFC, 0x00, + 0x00, 0x1F, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, + 0xFF, 0xC0, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0x00, 0x00, 0x07, 0xFF, 0xFC, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xF0, 0x00, 0x00, + 0x00, 0x7F, 0xFF, 0xC0, 0x00, 0x01, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x07, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xF0, + 0x00, 0x00, 0x7F, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x07, 0xFF, 0xFC, 0x00, 0x00, 0x1F, 0xFF, + 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x80, 0x00, + 0x00, 0x01, 0xFF, 0xFF, 0x00, 0x00, 0x07, 0xFF, 0xFC, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x7F, 0xFF, + 0xC0, 0x00, 0x01, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x0F, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xF0, 0x00, 0x00, 0x7F, + 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xFF, 0xFC, 0x00, + 0x00, 0x00, 0x07, 0xFF, 0xFC, 0x00, 0x00, 0x1F, 0xFF, 0xF0, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x01, 0xFF, + 0xFF, 0x00, 0x00, 0x07, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xC0, 0x00, 0x01, + 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xC0, + 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xF0, 0x00, 0x00, 0x7F, 0xFF, 0xC0, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x07, + 0xFF, 0xFC, 0x00, 0x00, 0x1F, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x07, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0x00, 0x00, + 0x07, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFE, + 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xC0, 0x00, 0x01, 0xFF, 0xFF, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00, + 0x1F, 0xFF, 0xF0, 0x00, 0x00, 0x7F, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x3F, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x07, 0xFF, 0xFC, 0x00, + 0x00, 0x1F, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFF, + 0xF0, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0x00, 0x00, 0x07, 0xFF, 0xFC, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xFF, 0xFC, 0x00, 0x00, 0x00, + 0x00, 0x7F, 0xFF, 0xC0, 0x00, 0x01, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x01, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xF0, + 0x00, 0x00, 0x7F, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, + 0xFF, 0x80, 0x00, 0x00, 0x00, 0x07, 0xFF, 0xFC, 0x00, 0x00, 0x1F, 0xFF, + 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xC0, 0x00, 0x00, + 0x00, 0x01, 0xFF, 0xFF, 0x00, 0x00, 0x0F, 0xFF, 0xFC, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, + 0xC0, 0x00, 0x03, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, + 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xF0, 0x00, 0x00, 0xFF, + 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFE, 0x00, 0x00, + 0x00, 0x00, 0x07, 0xFF, 0xFC, 0x00, 0x00, 0x3F, 0xFF, 0xE0, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x01, 0xFF, + 0xFF, 0x00, 0x00, 0x0F, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x3F, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xE0, 0x00, 0x03, + 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xF0, 0x00, + 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xF8, 0x00, 0x00, 0xFF, 0xFF, 0x80, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x07, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x03, + 0xFF, 0xFE, 0x00, 0x00, 0x3F, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x80, 0x00, + 0x1F, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x80, + 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xF0, 0x00, 0x07, 0xFF, 0xFC, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x00, + 0x0F, 0xFF, 0xFC, 0x00, 0x03, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x0F, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0x80, + 0x01, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xFF, 0xFC, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xF0, 0x00, 0xFF, 0xFF, 0xE0, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x1F, 0xFF, 0xFF, 0x80, 0xFF, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, 0x03, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, + 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xF0, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x07, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xFF, + 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x80, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, + 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xFF, 0xFC, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xFF, + 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xE0, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xFF, + 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xFE, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x03, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x3F, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xFF, + 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, + 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, + 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x00, + 0x00, 0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x1F, + 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xFF, + 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0x80, 0x00, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x00, + 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, + 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0x7F, + 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xE0, 0x07, 0xFF, 0xFC, + 0x00, 0x00, 0x00, 0x07, 0xFF, 0xFF, 0x00, 0x07, 0xFF, 0xF8, 0x00, 0x00, + 0x00, 0x1F, 0xFF, 0xFC, 0x00, 0x07, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x3F, + 0xFF, 0xF8, 0x00, 0x0F, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xE0, + 0x00, 0x0F, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xC0, 0x00, 0x1F, + 0xFF, 0xC0, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0x80, 0x00, 0x3F, 0xFF, 0x80, + 0x00, 0x00, 0x07, 0xFF, 0xFE, 0x00, 0x00, 0x7F, 0xFF, 0x00, 0x00, 0x00, + 0x0F, 0xFF, 0xFC, 0x00, 0x00, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x1F, 0xFF, + 0xF8, 0x00, 0x00, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xF0, 0x00, + 0x01, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xE0, 0x00, 0x03, 0xFF, + 0xF0, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xC0, 0x00, 0x07, 0xFF, 0xF0, 0x00, + 0x00, 0x01, 0xFF, 0xFF, 0x80, 0x00, 0x0F, 0xFF, 0xE0, 0x00, 0x00, 0x03, + 0xFF, 0xFF, 0x00, 0x00, 0x1F, 0xFF, 0xC0, 0x00, 0x00, 0x07, 0xFF, 0xFE, + 0x00, 0x00, 0x3F, 0xFF, 0x80, 0x00, 0x00, 0x0F, 0xFF, 0xFC, 0x00, 0x00, + 0x7F, 0xFF, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xF8, 0x00, 0x00, 0xFF, 0xFE, + 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xF0, 0x00, 0x01, 0xFF, 0xF8, 0x00, 0x00, + 0x00, 0x7F, 0xFF, 0xE0, 0x00, 0x07, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, + 0xFF, 0xE0, 0x00, 0x0F, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xC0, + 0x00, 0x1F, 0xFF, 0xC0, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0x80, 0x00, 0x3F, + 0xFF, 0x80, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0x00, 0x00, 0x7F, 0xFF, 0x00, + 0x00, 0x00, 0x07, 0xFF, 0xFF, 0x00, 0x01, 0xFF, 0xFE, 0x00, 0x00, 0x00, + 0x0F, 0xFF, 0xFE, 0x00, 0x03, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x0F, 0xFF, + 0xFC, 0x00, 0x07, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xF8, 0x00, + 0x1F, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xF8, 0x00, 0x3F, 0xFF, + 0x80, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xF0, 0x00, 0xFF, 0xFF, 0x00, 0x00, + 0x00, 0x00, 0x7F, 0xFF, 0xE0, 0x01, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x00, + 0xFF, 0xFF, 0xC0, 0x07, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFF, + 0xC0, 0x0F, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0x80, 0x3F, + 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0x00, 0x7F, 0xFF, 0x80, + 0x00, 0x00, 0x00, 0x07, 0xFF, 0xFF, 0x01, 0xFF, 0xFF, 0x00, 0x00, 0x00, + 0x00, 0x07, 0xFF, 0xFE, 0x03, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x0F, + 0xFF, 0xFC, 0x0F, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xFC, + 0x1F, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xF8, 0x7F, 0xFF, + 0xC0, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xF1, 0xFF, 0xFF, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xF3, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x7F, 0xFF, 0xEF, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, + 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0xFF, + 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, + 0x00, 0x00, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xFE, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x07, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFF, + 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xFF, 0xFE, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x7F, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, + 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFC, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x0F, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, + 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFE, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xFE, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x07, 0xFF, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x1F, 0xFF, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x7F, 0xFF, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFF, + 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xF0, + 0x00, 0x00, 0x08, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xE0, 0x00, 0x00, + 0x38, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x70, 0x00, + 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0x01, 0xF0, 0x00, 0x01, 0xFF, + 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x07, 0xF0, 0x00, 0x07, 0xFF, 0xFF, 0xFF, + 0xFF, 0x80, 0x00, 0x1F, 0xE0, 0x00, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, + 0x00, 0x3F, 0xE0, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xFF, + 0xC0, 0x00, 0xFF, 0xFF, 0xE7, 0xFF, 0xFE, 0x00, 0x03, 0xFF, 0xC0, 0x03, + 0xFF, 0xFF, 0xCF, 0xFF, 0xFE, 0x00, 0x07, 0xFF, 0xC0, 0x07, 0xFF, 0xFF, + 0x0F, 0xFF, 0xFC, 0x00, 0x1F, 0xFF, 0x80, 0x1F, 0xFF, 0xFC, 0x1F, 0xFF, + 0xF8, 0x00, 0x7F, 0xFF, 0x80, 0x3F, 0xFF, 0xF8, 0x1F, 0xFF, 0xF8, 0x00, + 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xE0, 0x3F, 0xFF, 0xF0, 0x03, 0xFF, 0xFF, + 0x01, 0xFF, 0xFF, 0x80, 0x7F, 0xFF, 0xF0, 0x0F, 0xFF, 0xFC, 0x07, 0xFF, + 0xFF, 0x00, 0x7F, 0xFF, 0xE0, 0x1F, 0xFF, 0xF0, 0x0F, 0xFF, 0xFC, 0x00, + 0xFF, 0xFF, 0xC0, 0x7F, 0xFF, 0xE0, 0x3F, 0xFF, 0xF8, 0x00, 0xFF, 0xFF, + 0xC0, 0xFF, 0xFF, 0x80, 0x7F, 0xFF, 0xE0, 0x01, 0xFF, 0xFF, 0x83, 0xFF, + 0xFE, 0x01, 0xFF, 0xFF, 0xC0, 0x01, 0xFF, 0xFF, 0x8F, 0xFF, 0xFC, 0x03, + 0xFF, 0xFF, 0x00, 0x03, 0xFF, 0xFF, 0x1F, 0xFF, 0xF0, 0x0F, 0xFF, 0xFE, + 0x00, 0x07, 0xFF, 0xFE, 0x7F, 0xFF, 0xC0, 0x1F, 0xFF, 0xF8, 0x00, 0x07, + 0xFF, 0xFE, 0xFF, 0xFF, 0x80, 0x3F, 0xFF, 0xF0, 0x00, 0x0F, 0xFF, 0xFF, + 0xFF, 0xFE, 0x00, 0xFF, 0xFF, 0xE0, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xF8, + 0x01, 0xFF, 0xFF, 0x80, 0x00, 0x1F, 0xFF, 0xFF, 0xFF, 0xF0, 0x03, 0xFF, + 0xFF, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xC0, 0x07, 0xFF, 0xFE, 0x00, + 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0x80, 0x1F, 0xFF, 0xF8, 0x00, 0x00, 0x7F, + 0xFF, 0xFF, 0xFE, 0x00, 0x3F, 0xFF, 0xF0, 0x00, 0x00, 0x7F, 0xFF, 0xFF, + 0xFC, 0x00, 0x7F, 0xFF, 0xE0, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, + 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xE0, 0x01, 0xFF, 0xFF, + 0x00, 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0x80, 0x07, 0xFF, 0xFE, 0x00, 0x00, + 0x03, 0xFF, 0xFF, 0xFF, 0x00, 0x0F, 0xFF, 0xFC, 0x00, 0x00, 0x03, 0xFF, + 0xFF, 0xFC, 0x00, 0x1F, 0xFF, 0xF8, 0x00, 0x00, 0x07, 0xFF, 0xFF, 0xF8, + 0x00, 0x3F, 0xFF, 0xF0, 0x00, 0x00, 0x07, 0xFF, 0xFF, 0xE0, 0x00, 0x7F, + 0xFF, 0xE0, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xC0, 0x00, 0xFF, 0xFF, 0xC0, + 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0x00, 0x01, 0xFF, 0xFF, 0x80, 0x00, 0x00, + 0x1F, 0xFF, 0xFE, 0x00, 0x03, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x3F, 0xFF, + 0xF8, 0x00, 0x07, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xF0, 0x00, + 0x0F, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xE0, 0x00, 0x1F, 0xFF, + 0xF8, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xE0, 0x00, 0x3F, 0xFF, 0xF0, 0x00, + 0x00, 0x0F, 0xFF, 0xFF, 0xC0, 0x00, 0x7F, 0xFF, 0xE0, 0x00, 0x00, 0x1F, + 0xFF, 0xFF, 0xC0, 0x00, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x7F, 0xFF, 0xFF, + 0x80, 0x01, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x80, 0x01, + 0xFF, 0xFF, 0x80, 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0x00, 0x03, 0xFF, 0xFF, + 0x80, 0x00, 0x0F, 0xFF, 0xFF, 0xFE, 0x00, 0x07, 0xFF, 0xFF, 0x00, 0x00, + 0x1F, 0xFF, 0xFF, 0xFE, 0x00, 0x0F, 0xFF, 0xFF, 0x00, 0x00, 0x7F, 0xFF, + 0xFF, 0xFC, 0x00, 0x1F, 0xFF, 0xFF, 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0xFC, + 0x00, 0x1F, 0xFF, 0xFF, 0x00, 0x07, 0xFF, 0xFF, 0xFF, 0xF8, 0x00, 0x3F, + 0xFF, 0xFF, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xF8, 0x00, 0x7F, 0xFF, 0xFF, + 0xF3, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xE0, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, + 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0xFF, 0xFF, 0xC0, 0x01, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xF1, 0xFF, 0xFF, 0x80, 0x03, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xC1, 0xFF, 0xFF, 0x80, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0x83, 0xFF, 0xFF, 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x03, 0xFF, + 0xFF, 0x00, 0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x07, 0xFF, 0xFE, 0x00, + 0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0x07, 0xFF, 0xFE, 0x00, 0x03, 0xFF, + 0xFF, 0xFF, 0xFF, 0x80, 0x0F, 0xFF, 0xFC, 0x00, 0x03, 0xFF, 0xFF, 0xFF, + 0xFC, 0x00, 0x1F, 0xFF, 0xFC, 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, + 0x1F, 0xFF, 0xF8, 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x3F, 0xFF, + 0xF0, 0x00, 0x00, 0xFF, 0xFF, 0xFC, 0x00, 0x00, 0x3F, 0xFF, 0xF0, 0x00, + 0x00, 0x7F, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, + 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFB, + 0xFF, 0xFF, 0x3F, 0xFF, 0xE7, 0xFF, 0xFC, 0xFF, 0xFF, 0x9F, 0xFF, 0xF3, + 0xFF, 0xFE, 0x7F, 0xFF, 0xCF, 0xFF, 0xF9, 0xFF, 0xFF, 0x3F, 0xFF, 0xC7, + 0xFF, 0xF8, 0x7F, 0xFF, 0x0F, 0xFF, 0xE1, 0xFF, 0xFC, 0x3F, 0xFF, 0x87, + 0xFF, 0xF0, 0xFF, 0xFE, 0x1F, 0xFF, 0xC3, 0xFF, 0xF0, 0x7F, 0xFE, 0x0F, + 0xFF, 0xC1, 0xFF, 0xF8, 0x1F, 0xFF, 0x03, 0xFF, 0xE0, 0x7F, 0xFC, 0x0F, + 0xFF, 0x81, 0xFF, 0xF0, 0x3F, 0xFE, 0x07, 0xFF, 0x80, 0xFF, 0xF0, 0x1F, + 0xFE, 0x03, 0xFF, 0xC0, 0x3F, 0xF8, 0x07, 0xFF, 0x00, 0xFF, 0xE0, 0x1F, + 0xFC, 0x03, 0xFF, 0x80, 0x7F, 0xF0, 0x0F, 0xFC, 0x01, 0xFF, 0x80, 0x3F, + 0xF0, 0x07, 0xFE, 0x00, 0xFF, 0xC0, 0x0F, 0xF8, 0x01, 0xFF, 0x00, 0x3F, + 0xE0, 0x07, 0xFC, 0x00, 0xFF, 0x80, 0x1F, 0xE0, 0x03, 0xFC, 0x00, 0x7F, + 0x80, 0x0F, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x7F, 0x00, 0x00, 0x3F, 0xFF, + 0x00, 0x03, 0xFF, 0xFF, 0x00, 0x0F, 0xFF, 0xFF, 0x00, 0x3F, 0xFF, 0xFF, + 0x00, 0x7F, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x01, 0xFF, 0xFF, 0xFF, + 0x03, 0xFF, 0xFF, 0xFF, 0x03, 0xFF, 0xFF, 0xFF, 0x07, 0xFF, 0xFF, 0xFF, + 0x0F, 0xFF, 0xFF, 0xFF, 0x0F, 0xFF, 0xFF, 0xFF, 0x1F, 0xFF, 0xFF, 0xFF, + 0x1F, 0xFF, 0xFF, 0xFF, 0x1F, 0xFF, 0xFF, 0xF0, 0x3F, 0xFF, 0xFF, 0x80, + 0x3F, 0xFF, 0xFE, 0x00, 0x3F, 0xFF, 0xFC, 0x00, 0x3F, 0xFF, 0xFC, 0x00, + 0x3F, 0xFF, 0xFC, 0x00, 0x7F, 0xFF, 0xF8, 0x00, 0x7F, 0xFF, 0xF8, 0x00, + 0x7F, 0xFF, 0xF8, 0x00, 0x7F, 0xFF, 0xF8, 0x00, 0x7F, 0xFF, 0xF8, 0x00, + 0x7F, 0xFF, 0xF0, 0x00, 0x7F, 0xFF, 0xF0, 0x00, 0x7F, 0xFF, 0xF0, 0x00, + 0x7F, 0xFF, 0xF0, 0x00, 0x7F, 0xFF, 0xF0, 0x00, 0xFF, 0xFF, 0xF0, 0x00, + 0xFF, 0xFF, 0xF0, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0xFF, 0xFF, 0xF0, 0x00, + 0xFF, 0xFF, 0xF0, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0xFF, 0xFF, 0xF0, 0x00, + 0xFF, 0xFF, 0xF0, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0xFF, 0xFF, 0xF0, 0x00, + 0xFF, 0xFF, 0xF0, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0xFF, 0xFF, 0xF0, 0x00, + 0xFF, 0xFF, 0xF0, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0xFF, 0xFF, 0xF0, 0x00, + 0xFF, 0xFF, 0xF0, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0xFF, 0xFF, 0xF0, 0x00, + 0xFF, 0xFF, 0xF0, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0xFF, 0xFF, 0xF0, 0x00, + 0xFF, 0xFF, 0xF0, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0xFF, 0xFF, 0xF0, 0x00, + 0xFF, 0xFF, 0xF0, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0xFF, 0xFF, 0xF0, 0x00, + 0xFF, 0xFF, 0xF0, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0xFF, 0xFF, 0xF0, 0x00, + 0xFF, 0xFF, 0xF0, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0xFF, 0xFF, 0xF0, 0x00, + 0xFF, 0xFF, 0xF0, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0xFF, 0xFF, 0xF0, 0x00, + 0xFF, 0xFF, 0xF0, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0xFF, 0xFF, 0xF0, 0x00, + 0xFF, 0xFF, 0xF0, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0xFF, 0xFF, 0xF0, 0x00, + 0xFF, 0xFF, 0xF0, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0xFF, 0xFF, 0xF0, 0x00, + 0xFF, 0xFF, 0xF0, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0xFF, 0xFF, 0xF0, 0x00, + 0xFF, 0xFF, 0xF0, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0xFF, 0xFF, 0xF0, 0x00, + 0xFF, 0xFF, 0xF0, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0xFF, 0xFF, 0xF0, 0x00, + 0xFF, 0xFF, 0xF0, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0xFF, 0xFF, 0xF0, 0x00, + 0xFF, 0xFF, 0xF0, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0xFF, 0xFF, 0xF0, 0x00, + 0xFF, 0xFF, 0xF0, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0xFF, 0xFF, 0xF0, 0x00, + 0xFF, 0xFF, 0xF0, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0xFF, 0xFF, 0xF0, 0x00, + 0xFF, 0xFF, 0xF0, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0xFF, 0xFF, 0xF0, 0x00, + 0xFF, 0xFF, 0xF0, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0xFF, 0xFF, 0xF0, 0x00, + 0xFF, 0xFF, 0xF0, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0xFF, 0xFF, 0xF0, 0x00, + 0xFF, 0xFF, 0xF0, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0xFF, 0xFF, 0xF0, 0x00, + 0xFF, 0xFF, 0xF0, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0xFF, 0xFF, 0xF0, 0x00, + 0xFF, 0xFF, 0xF0, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0xFF, 0xFF, 0xF0, 0x00, + 0xFF, 0xFF, 0xF0, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0xFF, 0xFF, 0xF0, 0x00, + 0xFF, 0xFF, 0xF0, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0xFF, 0xFF, 0xF0, 0x00, + 0xFF, 0xFF, 0xF0, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0xFF, 0xFF, 0xF0, 0x00, + 0xFF, 0xFF, 0xF0, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0xFF, 0xFF, 0xF0, 0x00, + 0xFF, 0xFF, 0xF0, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0xFF, 0xFF, 0xF0, 0x00, + 0xFF, 0xFF, 0xF0, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0xFF, 0xFF, 0xF0, 0x00, + 0xFF, 0xFF, 0xF0, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0xFF, 0xFF, 0xF0, 0x00, + 0xFF, 0xFF, 0xF0, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0xFF, 0xFF, 0xF0, 0x00, + 0xFF, 0xFF, 0xF0, 0x00, 0x7F, 0xFF, 0xF0, 0x00, 0x7F, 0xFF, 0xF0, 0x00, + 0x7F, 0xFF, 0xF0, 0x00, 0x7F, 0xFF, 0xF0, 0x00, 0x7F, 0xFF, 0xF0, 0x00, + 0x7F, 0xFF, 0xF8, 0x00, 0x7F, 0xFF, 0xF8, 0x00, 0x7F, 0xFF, 0xF8, 0x00, + 0x7F, 0xFF, 0xF8, 0x00, 0x7F, 0xFF, 0xF8, 0x00, 0x3F, 0xFF, 0xF8, 0x00, + 0x3F, 0xFF, 0xFC, 0x00, 0x3F, 0xFF, 0xFC, 0x00, 0x3F, 0xFF, 0xFE, 0x00, + 0x3F, 0xFF, 0xFF, 0x00, 0x1F, 0xFF, 0xFF, 0xE0, 0x1F, 0xFF, 0xFF, 0xFF, + 0x1F, 0xFF, 0xFF, 0xFF, 0x0F, 0xFF, 0xFF, 0xFF, 0x0F, 0xFF, 0xFF, 0xFF, + 0x07, 0xFF, 0xFF, 0xFF, 0x07, 0xFF, 0xFF, 0xFF, 0x03, 0xFF, 0xFF, 0xFF, + 0x01, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x7F, 0xFF, 0xFF, + 0x00, 0x3F, 0xFF, 0xFF, 0x00, 0x0F, 0xFF, 0xFF, 0x00, 0x03, 0xFF, 0xFF, + 0x00, 0x00, 0x7F, 0xFF, 0x00, 0x00, 0x01, 0xFF, 0xFE, 0x00, 0x00, 0x00, + 0xFF, 0xFE, 0x00, 0x00, 0xFF, 0xFF, 0xC0, 0x00, 0xFF, 0xFF, 0xF0, 0x00, + 0xFF, 0xFF, 0xFC, 0x00, 0xFF, 0xFF, 0xFE, 0x00, 0xFF, 0xFF, 0xFF, 0x00, + 0xFF, 0xFF, 0xFF, 0x80, 0xFF, 0xFF, 0xFF, 0xC0, 0xFF, 0xFF, 0xFF, 0xE0, + 0xFF, 0xFF, 0xFF, 0xE0, 0xFF, 0xFF, 0xFF, 0xF0, 0xFF, 0xFF, 0xFF, 0xF0, + 0xFF, 0xFF, 0xFF, 0xF8, 0xFF, 0xFF, 0xFF, 0xF8, 0x07, 0xFF, 0xFF, 0xFC, + 0x00, 0xFF, 0xFF, 0xFC, 0x00, 0x7F, 0xFF, 0xFC, 0x00, 0x3F, 0xFF, 0xFC, + 0x00, 0x3F, 0xFF, 0xFE, 0x00, 0x1F, 0xFF, 0xFE, 0x00, 0x1F, 0xFF, 0xFE, + 0x00, 0x1F, 0xFF, 0xFE, 0x00, 0x1F, 0xFF, 0xFE, 0x00, 0x0F, 0xFF, 0xFE, + 0x00, 0x0F, 0xFF, 0xFE, 0x00, 0x0F, 0xFF, 0xFF, 0x00, 0x0F, 0xFF, 0xFF, + 0x00, 0x0F, 0xFF, 0xFF, 0x00, 0x0F, 0xFF, 0xFF, 0x00, 0x0F, 0xFF, 0xFF, + 0x00, 0x0F, 0xFF, 0xFF, 0x00, 0x0F, 0xFF, 0xFF, 0x00, 0x0F, 0xFF, 0xFF, + 0x00, 0x0F, 0xFF, 0xFF, 0x00, 0x0F, 0xFF, 0xFF, 0x00, 0x0F, 0xFF, 0xFF, + 0x00, 0x0F, 0xFF, 0xFF, 0x00, 0x0F, 0xFF, 0xFF, 0x00, 0x0F, 0xFF, 0xFF, + 0x00, 0x0F, 0xFF, 0xFF, 0x00, 0x0F, 0xFF, 0xFF, 0x00, 0x0F, 0xFF, 0xFF, + 0x00, 0x0F, 0xFF, 0xFF, 0x00, 0x0F, 0xFF, 0xFF, 0x00, 0x0F, 0xFF, 0xFF, + 0x00, 0x0F, 0xFF, 0xFF, 0x00, 0x0F, 0xFF, 0xFF, 0x00, 0x0F, 0xFF, 0xFF, + 0x00, 0x0F, 0xFF, 0xFF, 0x00, 0x0F, 0xFF, 0xFF, 0x00, 0x0F, 0xFF, 0xFF, + 0x00, 0x0F, 0xFF, 0xFF, 0x00, 0x0F, 0xFF, 0xFF, 0x00, 0x0F, 0xFF, 0xFF, + 0x00, 0x0F, 0xFF, 0xFF, 0x00, 0x0F, 0xFF, 0xFF, 0x00, 0x0F, 0xFF, 0xFF, + 0x00, 0x0F, 0xFF, 0xFF, 0x00, 0x0F, 0xFF, 0xFF, 0x00, 0x0F, 0xFF, 0xFF, + 0x00, 0x0F, 0xFF, 0xFF, 0x00, 0x0F, 0xFF, 0xFF, 0x00, 0x0F, 0xFF, 0xFF, + 0x00, 0x0F, 0xFF, 0xFF, 0x00, 0x0F, 0xFF, 0xFF, 0x00, 0x0F, 0xFF, 0xFF, + 0x00, 0x0F, 0xFF, 0xFF, 0x00, 0x0F, 0xFF, 0xFF, 0x00, 0x0F, 0xFF, 0xFF, + 0x00, 0x0F, 0xFF, 0xFF, 0x00, 0x0F, 0xFF, 0xFF, 0x00, 0x0F, 0xFF, 0xFF, + 0x00, 0x0F, 0xFF, 0xFF, 0x00, 0x0F, 0xFF, 0xFF, 0x00, 0x0F, 0xFF, 0xFF, + 0x00, 0x0F, 0xFF, 0xFF, 0x00, 0x0F, 0xFF, 0xFF, 0x00, 0x0F, 0xFF, 0xFF, + 0x00, 0x0F, 0xFF, 0xFF, 0x00, 0x0F, 0xFF, 0xFF, 0x00, 0x0F, 0xFF, 0xFF, + 0x00, 0x0F, 0xFF, 0xFF, 0x00, 0x0F, 0xFF, 0xFF, 0x00, 0x0F, 0xFF, 0xFF, + 0x00, 0x0F, 0xFF, 0xFF, 0x00, 0x0F, 0xFF, 0xFF, 0x00, 0x0F, 0xFF, 0xFF, + 0x00, 0x0F, 0xFF, 0xFF, 0x00, 0x0F, 0xFF, 0xFF, 0x00, 0x0F, 0xFF, 0xFF, + 0x00, 0x0F, 0xFF, 0xFF, 0x00, 0x0F, 0xFF, 0xFF, 0x00, 0x0F, 0xFF, 0xFF, + 0x00, 0x0F, 0xFF, 0xFF, 0x00, 0x0F, 0xFF, 0xFF, 0x00, 0x0F, 0xFF, 0xFF, + 0x00, 0x0F, 0xFF, 0xFF, 0x00, 0x0F, 0xFF, 0xFF, 0x00, 0x0F, 0xFF, 0xFF, + 0x00, 0x0F, 0xFF, 0xFF, 0x00, 0x0F, 0xFF, 0xFF, 0x00, 0x0F, 0xFF, 0xFF, + 0x00, 0x0F, 0xFF, 0xFF, 0x00, 0x0F, 0xFF, 0xFF, 0x00, 0x0F, 0xFF, 0xFF, + 0x00, 0x0F, 0xFF, 0xFF, 0x00, 0x0F, 0xFF, 0xFF, 0x00, 0x0F, 0xFF, 0xFF, + 0x00, 0x0F, 0xFF, 0xFF, 0x00, 0x0F, 0xFF, 0xFF, 0x00, 0x0F, 0xFF, 0xFF, + 0x00, 0x0F, 0xFF, 0xFF, 0x00, 0x0F, 0xFF, 0xFF, 0x00, 0x0F, 0xFF, 0xFF, + 0x00, 0x0F, 0xFF, 0xFF, 0x00, 0x0F, 0xFF, 0xFF, 0x00, 0x0F, 0xFF, 0xFF, + 0x00, 0x0F, 0xFF, 0xFF, 0x00, 0x0F, 0xFF, 0xFF, 0x00, 0x0F, 0xFF, 0xFF, + 0x00, 0x0F, 0xFF, 0xFF, 0x00, 0x0F, 0xFF, 0xFF, 0x00, 0x0F, 0xFF, 0xFF, + 0x00, 0x0F, 0xFF, 0xFF, 0x00, 0x0F, 0xFF, 0xFF, 0x00, 0x0F, 0xFF, 0xFF, + 0x00, 0x0F, 0xFF, 0xFF, 0x00, 0x0F, 0xFF, 0xFF, 0x00, 0x0F, 0xFF, 0xFF, + 0x00, 0x0F, 0xFF, 0xFF, 0x00, 0x0F, 0xFF, 0xFF, 0x00, 0x0F, 0xFF, 0xFF, + 0x00, 0x0F, 0xFF, 0xFF, 0x00, 0x0F, 0xFF, 0xFF, 0x00, 0x0F, 0xFF, 0xFF, + 0x00, 0x0F, 0xFF, 0xFF, 0x00, 0x0F, 0xFF, 0xFF, 0x00, 0x0F, 0xFF, 0xFF, + 0x00, 0x0F, 0xFF, 0xFF, 0x00, 0x0F, 0xFF, 0xFF, 0x00, 0x0F, 0xFF, 0xFF, + 0x00, 0x0F, 0xFF, 0xFF, 0x00, 0x0F, 0xFF, 0xFF, 0x00, 0x0F, 0xFF, 0xFF, + 0x00, 0x0F, 0xFF, 0xFF, 0x00, 0x0F, 0xFF, 0xFE, 0x00, 0x0F, 0xFF, 0xFE, + 0x00, 0x1F, 0xFF, 0xFE, 0x00, 0x1F, 0xFF, 0xFE, 0x00, 0x1F, 0xFF, 0xFE, + 0x00, 0x1F, 0xFF, 0xFE, 0x00, 0x3F, 0xFF, 0xFE, 0x00, 0x3F, 0xFF, 0xFC, + 0x00, 0x7F, 0xFF, 0xFC, 0x00, 0xFF, 0xFF, 0xFC, 0x03, 0xFF, 0xFF, 0xFC, + 0xFF, 0xFF, 0xFF, 0xF8, 0xFF, 0xFF, 0xFF, 0xF8, 0xFF, 0xFF, 0xFF, 0xF8, + 0xFF, 0xFF, 0xFF, 0xF0, 0xFF, 0xFF, 0xFF, 0xF0, 0xFF, 0xFF, 0xFF, 0xE0, + 0xFF, 0xFF, 0xFF, 0xC0, 0xFF, 0xFF, 0xFF, 0x80, 0xFF, 0xFF, 0xFF, 0x80, + 0xFF, 0xFF, 0xFE, 0x00, 0xFF, 0xFF, 0xFC, 0x00, 0xFF, 0xFF, 0xF8, 0x00, + 0xFF, 0xFF, 0xC0, 0x00, 0xFF, 0xFE, 0x00, 0x00, 0xFF, 0xC0, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x7F, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, + 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFE, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x7F, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, + 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFE, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x3F, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, + 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFE, 0x00, 0x00, 0x80, + 0x01, 0x00, 0x00, 0x3F, 0xFE, 0x00, 0x00, 0x80, 0x01, 0xC0, 0x00, 0x3F, + 0xFE, 0x00, 0x03, 0xC0, 0x03, 0xE0, 0x00, 0x3F, 0xFC, 0x00, 0x07, 0xE0, + 0x07, 0xF0, 0x00, 0x3F, 0xFC, 0x00, 0x0F, 0xE0, 0x07, 0xFC, 0x00, 0x3F, + 0xFC, 0x00, 0x3F, 0xF0, 0x0F, 0xFE, 0x00, 0x3F, 0xFC, 0x00, 0x7F, 0xF0, + 0x0F, 0xFF, 0x00, 0x1F, 0xFC, 0x00, 0xFF, 0xF8, 0x1F, 0xFF, 0xC0, 0x1F, + 0xFC, 0x03, 0xFF, 0xFC, 0x3F, 0xFF, 0xE0, 0x1F, 0xFC, 0x07, 0xFF, 0xFC, + 0x3F, 0xFF, 0xF0, 0x1F, 0xFC, 0x0F, 0xFF, 0xFE, 0x7F, 0xFF, 0xFC, 0x1F, + 0xFC, 0x3F, 0xFF, 0xFE, 0x7F, 0xFF, 0xFE, 0x1F, 0xFC, 0x7F, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0x1F, 0xFC, 0xFF, 0xFF, 0xFF, 0x7F, 0xFF, 0xFF, 0xDF, + 0xFB, 0xFF, 0xFF, 0xFC, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, + 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x00, + 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x01, 0xFF, 0xFF, + 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xFE, 0x00, 0x00, + 0x00, 0x00, 0x1F, 0xFF, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x07, 0xFF, + 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x07, 0xFF, 0xFF, 0xE0, 0x00, 0x00, + 0x00, 0x00, 0x1F, 0xFF, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, + 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x00, + 0x00, 0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x1F, 0xFF, 0xFF, + 0xFF, 0xFF, 0xF8, 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x00, + 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x07, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xE0, 0x1F, 0xFF, 0xFF, 0xDF, 0xFB, 0xFF, 0xFF, 0xF8, + 0xFF, 0xFF, 0xFF, 0x9F, 0xF8, 0xFF, 0xFF, 0xFE, 0x7F, 0xFF, 0xFE, 0x1F, + 0xFC, 0x7F, 0xFF, 0xFF, 0x7F, 0xFF, 0xFC, 0x1F, 0xFC, 0x3F, 0xFF, 0xFF, + 0x3F, 0xFF, 0xF8, 0x1F, 0xFC, 0x1F, 0xFF, 0xFE, 0x1F, 0xFF, 0xF0, 0x1F, + 0xFC, 0x07, 0xFF, 0xFC, 0x1F, 0xFF, 0xC0, 0x1F, 0xFC, 0x03, 0xFF, 0xFC, + 0x0F, 0xFF, 0x80, 0x1F, 0xFC, 0x01, 0xFF, 0xF8, 0x0F, 0xFF, 0x00, 0x3F, + 0xFC, 0x00, 0x7F, 0xF8, 0x07, 0xFC, 0x00, 0x3F, 0xFC, 0x00, 0x3F, 0xF0, + 0x03, 0xF8, 0x00, 0x3F, 0xFC, 0x00, 0x1F, 0xF0, 0x03, 0xF0, 0x00, 0x3F, + 0xFC, 0x00, 0x0F, 0xE0, 0x01, 0xE0, 0x00, 0x3F, 0xFE, 0x00, 0x03, 0xC0, + 0x01, 0x80, 0x00, 0x3F, 0xFE, 0x00, 0x01, 0xC0, 0x01, 0x00, 0x00, 0x3F, + 0xFE, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x3F, 0xFE, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x3F, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, + 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFE, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x7F, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, + 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFE, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x7F, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, + 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0x80, 0x00, 0x00, 0x00, + 0x00, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x07, 0xFF, 0xE0, 0x00, 0x00, + 0x00, 0x00, 0x3F, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xF8, 0x00, + 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFE, + 0x00, 0x00, 0x00, 0x00, 0x03, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x1F, + 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x00, + 0x07, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0x00, 0x00, 0x00, + 0x00, 0x01, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xC0, 0x00, + 0x00, 0x00, 0x00, 0x7F, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x03, 0xFF, 0xF0, + 0x00, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, 0xFF, + 0xFC, 0x00, 0x00, 0x00, 0x00, 0x07, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x00, + 0x3F, 0xFF, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xC0, 0x00, 0x07, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, + 0x00, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x0F, + 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFE, 0x00, 0x00, 0x00, 0x00, + 0x03, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0x80, 0x00, 0x00, + 0x00, 0x00, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x07, 0xFF, 0xE0, 0x00, + 0x00, 0x00, 0x00, 0x3F, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xF8, + 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x7F, + 0xFE, 0x00, 0x00, 0x00, 0x00, 0x03, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, + 0x1F, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFC, 0x00, 0x00, 0x00, + 0x00, 0x07, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0x00, 0x00, + 0x00, 0x00, 0x01, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xC0, + 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFE, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0x03, 0xFF, + 0xC0, 0x07, 0xFF, 0x80, 0x1F, 0xFF, 0x00, 0x3F, 0xFC, 0x00, 0x7F, 0xF8, + 0x00, 0xFF, 0xF0, 0x01, 0xFF, 0xC0, 0x07, 0xFF, 0x80, 0x0F, 0xFF, 0x00, + 0x1F, 0xFE, 0x00, 0x3F, 0xF8, 0x00, 0xFF, 0xF0, 0x01, 0xFF, 0xE0, 0x03, + 0xFF, 0x80, 0x07, 0xFF, 0x00, 0x0F, 0xFE, 0x00, 0x3F, 0xF8, 0x00, 0x7F, + 0xF0, 0x00, 0xFF, 0xE0, 0x01, 0xFF, 0xC0, 0x03, 0xFF, 0x00, 0x0F, 0xFE, + 0x00, 0x1F, 0xFC, 0x00, 0x3F, 0xF0, 0x00, 0x7F, 0xE0, 0x00, 0xFF, 0xC0, + 0x03, 0xFF, 0x80, 0x07, 0xFE, 0x00, 0x0F, 0xFC, 0x00, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0x00, + 0x00, 0x00, 0x00, 0x07, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFF, + 0xF8, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, + 0x7F, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xC0, 0x00, 0x00, + 0x00, 0x01, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x07, 0xFF, 0xFE, 0x00, + 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x1F, 0xFF, + 0xF8, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x00, + 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0x80, 0x00, 0x00, + 0x00, 0x03, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x07, 0xFF, 0xFC, 0x00, + 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, + 0xF0, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x00, + 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0x00, 0x00, 0x00, + 0x00, 0x07, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFC, 0x00, + 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, + 0xE0, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x01, + 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x03, 0xFF, 0xFE, 0x00, 0x00, 0x00, + 0x00, 0x07, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xF8, 0x00, + 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, + 0xC0, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x03, + 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x07, 0xFF, 0xFE, 0x00, 0x00, 0x00, + 0x00, 0x0F, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xF0, 0x00, + 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, + 0xC0, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x03, + 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFC, 0x00, 0x00, 0x00, + 0x00, 0x1F, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xF0, 0x00, + 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFF, + 0x80, 0x00, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x07, + 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xF8, 0x00, 0x00, 0x00, + 0x00, 0x3F, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xE0, 0x00, + 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFF, + 0x00, 0x00, 0x00, 0x00, 0x07, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x0F, + 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xF8, 0x00, 0x00, 0x00, + 0x00, 0x3F, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xC0, 0x00, + 0x00, 0x00, 0x01, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x03, 0xFF, 0xFF, + 0x00, 0x00, 0x00, 0x00, 0x07, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x1F, + 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xF0, 0x00, 0x00, 0x00, + 0x00, 0x7F, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x80, 0x00, + 0x00, 0x00, 0x03, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x07, 0xFF, 0xFE, + 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x1F, + 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xE0, 0x00, 0x00, 0x00, + 0x00, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0x80, 0x00, + 0x00, 0x00, 0x03, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x07, 0xFF, 0xFC, + 0x00, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x3F, + 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xC0, 0x00, 0x00, 0x00, + 0x00, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0x00, 0x00, + 0x00, 0x00, 0x07, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xF8, + 0x00, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x7F, + 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x00, + 0x01, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x03, 0xFF, 0xFE, 0x00, 0x00, + 0x00, 0x00, 0x0F, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xF8, + 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x7F, + 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00, + 0x03, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x07, 0xFF, 0xFC, 0x00, 0x00, + 0x00, 0x00, 0x0F, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xF0, + 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x00, 0xFF, + 0xFF, 0x80, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, + 0x07, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFC, 0x00, 0x00, + 0x00, 0x00, 0x1F, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xE0, + 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x01, 0xFF, + 0xFF, 0x80, 0x00, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, + 0x07, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xF8, 0x00, 0x00, + 0x00, 0x00, 0x3F, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xE0, + 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x03, 0xFF, + 0xFF, 0x00, 0x00, 0x00, 0x00, 0x07, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x00, + 0x0F, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xF0, 0x00, 0x00, + 0x00, 0x00, 0x7F, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xC0, + 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x03, 0xFF, + 0xFE, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x00, + 0x1F, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xF0, 0x00, 0x00, + 0x00, 0x00, 0x7F, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0x80, + 0x00, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x07, 0xFF, + 0xFE, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x00, + 0x1F, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xE0, 0x00, 0x00, + 0x00, 0x00, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0x00, + 0x00, 0x00, 0x00, 0x03, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFF, + 0xFC, 0x00, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x00, + 0x3F, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xC0, 0x00, 0x00, + 0x00, 0x01, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0x00, + 0x00, 0x00, 0x00, 0x07, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFF, + 0xF8, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, + 0x7F, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x80, 0x00, 0x00, + 0x00, 0x01, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x07, 0xFF, 0xFE, 0x00, + 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x1F, 0xFF, + 0xF0, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x00, + 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0x80, 0x00, 0x00, + 0x00, 0x03, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x07, 0xFF, 0xFC, 0x00, + 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, + 0xF0, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x07, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFF, + 0xF8, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x07, + 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, + 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x1F, 0xFF, 0xFF, + 0xFF, 0xFF, 0xF8, 0x00, 0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x01, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0x00, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x03, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFE, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, + 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x07, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xC0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x1F, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x07, 0xFF, 0xFF, 0xF8, 0x0F, 0xFF, 0xFF, + 0xF0, 0xFF, 0xFF, 0xFC, 0x00, 0x7F, 0xFF, 0xFE, 0x1F, 0xFF, 0xFF, 0x00, + 0x07, 0xFF, 0xFF, 0xC3, 0xFF, 0xFF, 0xC0, 0x00, 0x7F, 0xFF, 0xF8, 0xFF, + 0xFF, 0xF8, 0x00, 0x0F, 0xFF, 0xFF, 0x1F, 0xFF, 0xFE, 0x00, 0x00, 0xFF, + 0xFF, 0xF3, 0xFF, 0xFF, 0xC0, 0x00, 0x1F, 0xFF, 0xFE, 0x7F, 0xFF, 0xF8, + 0x00, 0x03, 0xFF, 0xFF, 0xCF, 0xFF, 0xFE, 0x00, 0x00, 0x3F, 0xFF, 0xF9, + 0xFF, 0xFF, 0xC0, 0x00, 0x07, 0xFF, 0xFF, 0x7F, 0xFF, 0xF8, 0x00, 0x00, + 0xFF, 0xFF, 0xEF, 0xFF, 0xFF, 0x00, 0x00, 0x1F, 0xFF, 0xFD, 0xFF, 0xFF, + 0xE0, 0x00, 0x03, 0xFF, 0xFF, 0xBF, 0xFF, 0xFC, 0x00, 0x00, 0x7F, 0xFF, + 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0x00, + 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, + 0xFF, 0x80, 0x00, 0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFE, 0x00, 0x00, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, + 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x00, 0x00, 0x7F, 0xFF, 0xFF, + 0xFF, 0xFF, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0x00, 0x01, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, + 0x80, 0x00, 0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFE, 0x00, 0x00, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, + 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, + 0xFF, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0x00, 0x01, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, + 0x00, 0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFE, 0x00, 0x00, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0x03, + 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, + 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0x00, 0x01, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFC, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x00, + 0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFE, 0x00, 0x00, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0x03, 0xFF, + 0xFF, 0xFF, 0xFF, 0xF8, 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, + 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0x00, 0x01, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFC, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x07, + 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, + 0x00, 0x00, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0x03, 0xFF, 0xFF, + 0xFF, 0xFF, 0xF8, 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, + 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFC, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x07, 0xFF, + 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x00, + 0x00, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0x03, 0xFF, 0xFF, 0xFF, + 0xFF, 0xF8, 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x0F, + 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, + 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x07, 0xFF, 0xFF, + 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x00, 0x00, + 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, + 0xF8, 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x0F, 0xFF, + 0xFF, 0xFF, 0xFF, 0xE0, 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, + 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x07, 0xFF, 0xFF, 0xFF, + 0xFF, 0xF0, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x00, 0x00, 0x1F, + 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, + 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x0F, 0xFF, 0xFF, + 0xFF, 0xFF, 0xE0, 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x00, + 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x07, 0xFF, 0xFF, 0xFF, 0xFF, + 0xF0, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x00, 0x00, 0x1F, 0xFF, + 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x00, + 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, + 0xFF, 0xE0, 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x00, 0x3F, + 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, + 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x00, 0x00, 0x1F, 0xFF, 0xFF, + 0xFF, 0xFF, 0xC0, 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x00, 0x00, + 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, + 0xE0, 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x00, 0x3F, 0xFF, + 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, + 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x00, 0x00, 0x1F, 0xFF, 0xFF, 0xFF, + 0xFF, 0xC0, 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x00, 0x00, 0x7F, + 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, + 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x00, 0x00, 0x3F, 0xFF, 0xFF, + 0xFF, 0xFF, 0xC0, 0x00, 0x07, 0xFF, 0xFF, 0x7F, 0xFF, 0xF8, 0x00, 0x00, + 0xFF, 0xFF, 0xEF, 0xFF, 0xFF, 0x00, 0x00, 0x1F, 0xFF, 0xFC, 0xFF, 0xFF, + 0xE0, 0x00, 0x03, 0xFF, 0xFF, 0x9F, 0xFF, 0xFC, 0x00, 0x00, 0x7F, 0xFF, + 0xF3, 0xFF, 0xFF, 0x80, 0x00, 0x0F, 0xFF, 0xFE, 0x7F, 0xFF, 0xF0, 0x00, + 0x03, 0xFF, 0xFF, 0xCF, 0xFF, 0xFE, 0x00, 0x00, 0x7F, 0xFF, 0xF9, 0xFF, + 0xFF, 0xE0, 0x00, 0x0F, 0xFF, 0xFF, 0x3F, 0xFF, 0xFC, 0x00, 0x01, 0xFF, + 0xFF, 0xE3, 0xFF, 0xFF, 0x80, 0x00, 0x3F, 0xFF, 0xF8, 0x7F, 0xFF, 0xF8, + 0x00, 0x0F, 0xFF, 0xFF, 0x0F, 0xFF, 0xFF, 0x00, 0x01, 0xFF, 0xFF, 0xE1, + 0xFF, 0xFF, 0xF0, 0x00, 0x7F, 0xFF, 0xFC, 0x1F, 0xFF, 0xFF, 0x00, 0x1F, + 0xFF, 0xFF, 0x03, 0xFF, 0xFF, 0xFC, 0x1F, 0xFF, 0xFF, 0xE0, 0x7F, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0x1F, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFC, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x3F, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xF8, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x00, 0x03, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, + 0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, + 0xFF, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x3F, + 0xFF, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xE0, 0x00, + 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x03, 0xFF, + 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0x80, 0x00, 0x00, + 0x3F, 0xFF, 0xC0, 0x00, 0x00, 0x1F, 0xFF, 0xE0, 0x00, 0x00, 0x1F, 0xFF, + 0xF0, 0x00, 0x00, 0x1F, 0xFF, 0xF8, 0x00, 0x00, 0x0F, 0xFF, 0xFC, 0x00, + 0x00, 0x0F, 0xFF, 0xFE, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0x00, 0x00, 0x0F, + 0xFF, 0xFF, 0x80, 0x00, 0x0F, 0xFF, 0xFF, 0xC0, 0x00, 0x0F, 0xFF, 0xFF, + 0xE0, 0x00, 0x1F, 0xFF, 0xFF, 0xF0, 0x00, 0x1F, 0xFF, 0xFF, 0xF8, 0x00, + 0x3F, 0xFF, 0xFF, 0xFC, 0x00, 0x7F, 0xFF, 0xFF, 0xFE, 0x00, 0xFF, 0xFF, + 0xFF, 0xFF, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0x87, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFD, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFC, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x7F, 0xFF, 0xFF, 0xFF, 0xF8, 0x3F, + 0xFF, 0xFF, 0xFF, 0xE0, 0x1F, 0xFF, 0xFF, 0xFF, 0xC0, 0x0F, 0xFF, 0xFF, + 0xFF, 0x00, 0x07, 0xFF, 0xFF, 0xF0, 0x00, 0x03, 0xFF, 0xFF, 0xC0, 0x00, + 0x01, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x7F, + 0xFF, 0xF8, 0x00, 0x00, 0x3F, 0xFF, 0xFC, 0x00, 0x00, 0x1F, 0xFF, 0xFE, + 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0x00, 0x00, 0x07, 0xFF, 0xFF, 0x80, 0x00, + 0x03, 0xFF, 0xFF, 0xC0, 0x00, 0x01, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0xFF, + 0xFF, 0xF0, 0x00, 0x00, 0x7F, 0xFF, 0xF8, 0x00, 0x00, 0x3F, 0xFF, 0xFC, + 0x00, 0x00, 0x1F, 0xFF, 0xFE, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0x00, 0x00, + 0x07, 0xFF, 0xFF, 0x80, 0x00, 0x03, 0xFF, 0xFF, 0xC0, 0x00, 0x01, 0xFF, + 0xFF, 0xE0, 0x00, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x7F, 0xFF, 0xF8, + 0x00, 0x00, 0x3F, 0xFF, 0xFC, 0x00, 0x00, 0x1F, 0xFF, 0xFE, 0x00, 0x00, + 0x0F, 0xFF, 0xFF, 0x00, 0x00, 0x07, 0xFF, 0xFF, 0x80, 0x00, 0x03, 0xFF, + 0xFF, 0xC0, 0x00, 0x01, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0xFF, 0xFF, 0xF0, + 0x00, 0x00, 0x7F, 0xFF, 0xF8, 0x00, 0x00, 0x3F, 0xFF, 0xFC, 0x00, 0x00, + 0x1F, 0xFF, 0xFE, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0x00, 0x00, 0x07, 0xFF, + 0xFF, 0x80, 0x00, 0x03, 0xFF, 0xFF, 0xC0, 0x00, 0x01, 0xFF, 0xFF, 0xE0, + 0x00, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x7F, 0xFF, 0xF8, 0x00, 0x00, + 0x3F, 0xFF, 0xFC, 0x00, 0x00, 0x1F, 0xFF, 0xFE, 0x00, 0x00, 0x0F, 0xFF, + 0xFF, 0x00, 0x00, 0x07, 0xFF, 0xFF, 0x80, 0x00, 0x03, 0xFF, 0xFF, 0xC0, + 0x00, 0x01, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, + 0x7F, 0xFF, 0xF8, 0x00, 0x00, 0x3F, 0xFF, 0xFC, 0x00, 0x00, 0x1F, 0xFF, + 0xFE, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0x00, 0x00, 0x07, 0xFF, 0xFF, 0x80, + 0x00, 0x03, 0xFF, 0xFF, 0xC0, 0x00, 0x01, 0xFF, 0xFF, 0xE0, 0x00, 0x00, + 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x7F, 0xFF, 0xF8, 0x00, 0x00, 0x3F, 0xFF, + 0xFC, 0x00, 0x00, 0x1F, 0xFF, 0xFE, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0x00, + 0x00, 0x07, 0xFF, 0xFF, 0x80, 0x00, 0x03, 0xFF, 0xFF, 0xC0, 0x00, 0x01, + 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x7F, 0xFF, + 0xF8, 0x00, 0x00, 0x3F, 0xFF, 0xFC, 0x00, 0x00, 0x1F, 0xFF, 0xFE, 0x00, + 0x00, 0x0F, 0xFF, 0xFF, 0x00, 0x00, 0x07, 0xFF, 0xFF, 0x80, 0x00, 0x03, + 0xFF, 0xFF, 0xC0, 0x00, 0x01, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0xFF, 0xFF, + 0xF0, 0x00, 0x00, 0x7F, 0xFF, 0xF8, 0x00, 0x00, 0x3F, 0xFF, 0xFC, 0x00, + 0x00, 0x1F, 0xFF, 0xFE, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0x00, 0x00, 0x07, + 0xFF, 0xFF, 0x80, 0x00, 0x03, 0xFF, 0xFF, 0xC0, 0x00, 0x01, 0xFF, 0xFF, + 0xE0, 0x00, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x7F, 0xFF, 0xF8, 0x00, + 0x00, 0x3F, 0xFF, 0xFC, 0x00, 0x00, 0x1F, 0xFF, 0xFE, 0x00, 0x00, 0x0F, + 0xFF, 0xFF, 0x00, 0x00, 0x07, 0xFF, 0xFF, 0x80, 0x00, 0x03, 0xFF, 0xFF, + 0xC0, 0x00, 0x01, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0xFF, 0xFF, 0xF0, 0x00, + 0x00, 0x7F, 0xFF, 0xF8, 0x00, 0x00, 0x3F, 0xFF, 0xFC, 0x00, 0x00, 0x1F, + 0xFF, 0xFE, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0x00, 0x00, 0x07, 0xFF, 0xFF, + 0x80, 0x00, 0x03, 0xFF, 0xFF, 0xC0, 0x00, 0x01, 0xFF, 0xFF, 0xE0, 0x00, + 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x7F, 0xFF, 0xF8, 0x00, 0x00, 0x3F, + 0xFF, 0xFC, 0x00, 0x00, 0x1F, 0xFF, 0xFE, 0x00, 0x00, 0x0F, 0xFF, 0xFF, + 0x00, 0x00, 0x07, 0xFF, 0xFF, 0x80, 0x00, 0x03, 0xFF, 0xFF, 0xC0, 0x00, + 0x01, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x7F, + 0xFF, 0xF8, 0x00, 0x00, 0x3F, 0xFF, 0xFC, 0x00, 0x00, 0x1F, 0xFF, 0xFE, + 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0x00, 0x00, 0x07, 0xFF, 0xFF, 0x80, 0x00, + 0x03, 0xFF, 0xFF, 0xC0, 0x00, 0x01, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0xFF, + 0xFF, 0xF0, 0x00, 0x00, 0x7F, 0xFF, 0xF8, 0x00, 0x00, 0x3F, 0xFF, 0xFC, + 0x00, 0x00, 0x1F, 0xFF, 0xFE, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0x00, 0x00, + 0x07, 0xFF, 0xFF, 0x80, 0x00, 0x03, 0xFF, 0xFF, 0xC0, 0x00, 0x01, 0xFF, + 0xFF, 0xE0, 0x00, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x7F, 0xFF, 0xF8, + 0x00, 0x00, 0x3F, 0xFF, 0xFC, 0x00, 0x00, 0x1F, 0xFF, 0xFE, 0x00, 0x00, + 0x01, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xFF, 0x80, 0x00, + 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xFF, + 0xFE, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0xFF, + 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, + 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0x80, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0x00, 0x7F, 0xFF, + 0xFF, 0xFF, 0xFF, 0xF8, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, + 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0x80, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0x1F, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xF0, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x0F, + 0xFF, 0xFF, 0xE0, 0x7F, 0xFF, 0xFE, 0x07, 0xFF, 0xFF, 0xC0, 0x0F, 0xFF, + 0xFF, 0x03, 0xFF, 0xFF, 0xC0, 0x03, 0xFF, 0xFF, 0x81, 0xFF, 0xFF, 0xC0, + 0x00, 0xFF, 0xFF, 0xE1, 0xFF, 0xFF, 0xE0, 0x00, 0x7F, 0xFF, 0xF0, 0xFF, + 0xFF, 0xF0, 0x00, 0x3F, 0xFF, 0xF8, 0x7F, 0xFF, 0xF0, 0x00, 0x0F, 0xFF, + 0xFC, 0x3F, 0xFF, 0xF8, 0x00, 0x07, 0xFF, 0xFF, 0x1F, 0xFF, 0xFC, 0x00, + 0x03, 0xFF, 0xFF, 0x8F, 0xFF, 0xFC, 0x00, 0x01, 0xFF, 0xFF, 0xCF, 0xFF, + 0xFE, 0x00, 0x00, 0xFF, 0xFF, 0xE7, 0xFF, 0xFF, 0x00, 0x00, 0x3F, 0xFF, + 0xF3, 0xFF, 0xFF, 0x80, 0x00, 0x1F, 0xFF, 0xF9, 0xFF, 0xFF, 0xC0, 0x00, + 0x0F, 0xFF, 0xFC, 0xFF, 0xFF, 0xE0, 0x00, 0x07, 0xFF, 0xFF, 0x7F, 0xFF, + 0xF0, 0x00, 0x03, 0xFF, 0xFF, 0xBF, 0xFF, 0xF8, 0x00, 0x01, 0xFF, 0xFF, + 0xDF, 0xFF, 0xFC, 0x00, 0x00, 0xFF, 0xFF, 0xEF, 0xFF, 0xFE, 0x00, 0x00, + 0x7F, 0xFF, 0xF7, 0xFF, 0xFF, 0x00, 0x00, 0x3F, 0xFF, 0xFB, 0xFF, 0xFF, + 0x80, 0x00, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0x0F, 0xFF, 0xFF, + 0xFF, 0xFF, 0xE0, 0x00, 0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x03, + 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, + 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x00, 0x00, 0x7F, 0xFF, 0xFF, + 0xFF, 0xFF, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x1F, + 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, + 0x00, 0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x03, 0xFF, 0xFF, 0xFF, + 0xFF, 0xF8, 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x00, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFE, 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, + 0x00, 0x7F, 0xFF, 0xF7, 0xFF, 0xFF, 0x80, 0x00, 0x3F, 0xFF, 0xFB, 0xFF, + 0xFF, 0xC0, 0x00, 0x1F, 0xFF, 0xFD, 0xFF, 0xFF, 0xE0, 0x00, 0x0F, 0xFF, + 0xFE, 0xFF, 0xFF, 0xF0, 0x00, 0x07, 0xFF, 0xFF, 0x7F, 0xFF, 0xF8, 0x00, + 0x03, 0xFF, 0xFF, 0xBF, 0xFF, 0xFC, 0x00, 0x03, 0xFF, 0xFF, 0x9F, 0xFF, + 0xFE, 0x00, 0x01, 0xFF, 0xFF, 0xCF, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, + 0xE0, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, + 0x7F, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xF8, 0x00, 0x00, + 0x00, 0x00, 0x3F, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xFC, + 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x0F, + 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x07, 0xFF, 0xFF, 0x00, 0x00, 0x00, + 0x00, 0x07, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xC0, + 0x00, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x03, 0xFF, + 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x00, + 0x01, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xF0, 0x00, + 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, + 0xF8, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x00, + 0x7F, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xFE, 0x00, 0x00, + 0x00, 0x00, 0x3F, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xFF, + 0x00, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x1F, + 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0x80, 0x00, 0x00, + 0x00, 0x0F, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x07, 0xFF, 0xFF, 0xC0, + 0x00, 0x00, 0x00, 0x07, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x03, 0xFF, + 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x00, + 0x03, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0xF0, 0x00, + 0x00, 0x00, 0x01, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, + 0xF8, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x00, + 0xFF, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xFC, 0x00, 0x00, + 0x00, 0x00, 0x7F, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xFE, + 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x1F, + 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xFF, 0x00, 0x00, 0x00, + 0x00, 0x0F, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0x80, + 0x00, 0x00, 0x00, 0x07, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x07, 0xFF, + 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x00, + 0x03, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0xF0, 0x00, + 0x00, 0x00, 0x01, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, + 0xF0, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x00, + 0x7F, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xFC, 0x00, 0x00, + 0x00, 0x00, 0x3F, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xFE, + 0x00, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x0F, + 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0x80, 0x00, 0x00, + 0x00, 0x07, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xC0, + 0x00, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x01, 0xFF, + 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, + 0x00, 0x7F, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xF8, 0x00, + 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x1F, 0xFF, + 0xFC, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x00, + 0x07, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x07, 0xFF, 0xFF, 0x80, 0x00, + 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFF, + 0xC0, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x00, + 0x7F, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xF8, 0x00, 0x00, + 0x00, 0x00, 0x1F, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0x87, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC3, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE3, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xF1, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFC, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x3F, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0x8F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC7, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xE3, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF1, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFC, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x03, + 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0xFC, 0x00, 0x00, + 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x07, 0xFF, 0xFF, + 0xFF, 0xF8, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x00, + 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x00, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xC0, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x07, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xF8, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, + 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x3F, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFC, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x0F, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0xFF, 0xFF, 0xFF, 0x01, 0xFF, + 0xFF, 0xFC, 0x07, 0xFF, 0xFF, 0xE0, 0x03, 0xFF, 0xFF, 0xF0, 0x3F, 0xFF, + 0xFE, 0x00, 0x0F, 0xFF, 0xFF, 0x83, 0xFF, 0xFF, 0xE0, 0x00, 0x3F, 0xFF, + 0xFC, 0x1F, 0xFF, 0xFE, 0x00, 0x01, 0xFF, 0xFF, 0xF0, 0xFF, 0xFF, 0xF0, + 0x00, 0x07, 0xFF, 0xFF, 0x87, 0xFF, 0xFF, 0x00, 0x00, 0x3F, 0xFF, 0xFC, + 0x3F, 0xFF, 0xF8, 0x00, 0x01, 0xFF, 0xFF, 0xE3, 0xFF, 0xFF, 0xC0, 0x00, + 0x07, 0xFF, 0xFF, 0x1F, 0xFF, 0xFE, 0x00, 0x00, 0x3F, 0xFF, 0xFC, 0xFF, + 0xFF, 0xE0, 0x00, 0x01, 0xFF, 0xFF, 0xE7, 0xFF, 0xFF, 0x00, 0x00, 0x0F, + 0xFF, 0xFF, 0x3F, 0xFF, 0xF8, 0x00, 0x00, 0x7F, 0xFF, 0xF9, 0xFF, 0xFF, + 0xC0, 0x00, 0x01, 0xFF, 0xFF, 0xCF, 0xFF, 0xFE, 0x00, 0x00, 0x0F, 0xFF, + 0xFE, 0x7F, 0xFF, 0xF0, 0x00, 0x00, 0x7F, 0xFF, 0xF3, 0xFF, 0xFF, 0x80, + 0x00, 0x03, 0xFF, 0xFF, 0x9F, 0xFF, 0xFC, 0x00, 0x00, 0x1F, 0xFF, 0xFD, + 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0xFF, 0xFF, 0xEF, 0xFF, 0xFF, 0x00, 0x00, + 0x07, 0xFF, 0xFF, 0x7F, 0xFF, 0xF8, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, + 0xFF, 0xC0, 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x00, 0x00, 0x0F, + 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, + 0x80, 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x00, 0x1F, 0xFF, + 0xFD, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x00, + 0x00, 0x07, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xF8, + 0x00, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00, + 0x0F, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xF0, 0x00, + 0x00, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, 0x3F, + 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0xE0, 0x00, 0x00, + 0x00, 0x00, 0x0F, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, + 0xF0, 0x00, 0x00, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00, + 0x00, 0x1F, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0xC0, + 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x7F, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x07, 0xFF, 0xFF, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x03, 0xFF, + 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xFC, 0x00, 0x00, 0x00, + 0x00, 0x03, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xFE, + 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x01, 0xFF, + 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, + 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x03, 0xFF, 0xFF, + 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xFF, 0xFE, 0x00, 0x00, 0x00, + 0x00, 0xFF, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x07, 0xFF, 0xFF, 0xFC, + 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x01, + 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0x80, + 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x03, 0xFF, + 0xFF, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xFF, 0xFF, 0xE0, 0x00, + 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x07, 0xFF, 0xFF, + 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xF0, 0x00, 0x00, + 0x00, 0x00, 0x1F, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, + 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, + 0x00, 0x03, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFE, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x00, + 0x01, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFE, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x03, + 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFE, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x03, 0xFF, + 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xFE, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x07, 0xFF, 0xFF, + 0x80, 0x00, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x07, 0xFF, 0xFF, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x01, + 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, + 0xE0, 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x03, 0xFF, + 0xFF, 0xFF, 0xFF, 0xF8, 0x00, 0x00, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, + 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x00, 0x00, 0x07, 0xFF, 0xFF, + 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x00, + 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, + 0xFF, 0xE0, 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x03, + 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x00, 0x00, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, + 0xC0, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x00, 0x00, 0x07, 0xFF, + 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, + 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x00, 0x0F, 0xFF, 0xFF, + 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x7F, 0xFF, 0xF7, 0xFF, 0xFF, 0x00, 0x00, + 0x03, 0xFF, 0xFF, 0x9F, 0xFF, 0xF8, 0x00, 0x00, 0x1F, 0xFF, 0xFC, 0xFF, + 0xFF, 0xC0, 0x00, 0x00, 0xFF, 0xFF, 0xE7, 0xFF, 0xFE, 0x00, 0x00, 0x0F, + 0xFF, 0xFF, 0x3F, 0xFF, 0xF0, 0x00, 0x00, 0x7F, 0xFF, 0xF9, 0xFF, 0xFF, + 0xC0, 0x00, 0x03, 0xFF, 0xFF, 0xCF, 0xFF, 0xFE, 0x00, 0x00, 0x1F, 0xFF, + 0xFE, 0x7F, 0xFF, 0xF0, 0x00, 0x00, 0xFF, 0xFF, 0xE3, 0xFF, 0xFF, 0x80, + 0x00, 0x07, 0xFF, 0xFF, 0x0F, 0xFF, 0xFC, 0x00, 0x00, 0x7F, 0xFF, 0xF8, + 0x7F, 0xFF, 0xF0, 0x00, 0x03, 0xFF, 0xFF, 0xC3, 0xFF, 0xFF, 0x80, 0x00, + 0x1F, 0xFF, 0xFC, 0x1F, 0xFF, 0xFE, 0x00, 0x01, 0xFF, 0xFF, 0xE0, 0xFF, + 0xFF, 0xF0, 0x00, 0x1F, 0xFF, 0xFF, 0x03, 0xFF, 0xFF, 0xC0, 0x01, 0xFF, + 0xFF, 0xF8, 0x1F, 0xFF, 0xFF, 0x80, 0x1F, 0xFF, 0xFF, 0x80, 0xFF, 0xFF, + 0xFF, 0x87, 0xFF, 0xFF, 0xFC, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xC0, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x00, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xE0, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, + 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0x80, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x00, 0x0F, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFC, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0x03, 0xFF, + 0xFF, 0xFF, 0xFF, 0xF8, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, + 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x7F, 0xFF, + 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xE0, 0x00, 0x00, + 0x00, 0x00, 0xFF, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0xF0, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xFE, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x01, + 0xFF, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x00, + 0x01, 0xFF, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xFF, + 0x80, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, + 0x00, 0x01, 0xFF, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, + 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xF8, 0x00, 0x00, + 0x00, 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, + 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xFC, 0x00, + 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, + 0x3F, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x07, 0xFF, 0xFF, 0xFE, + 0x00, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x00, + 0x00, 0x3F, 0xFF, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x07, 0xFF, 0xFF, + 0xFF, 0x00, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0xE0, 0x00, 0x00, + 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x07, 0xFF, + 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, + 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x07, + 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xF8, + 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, + 0x07, 0xFF, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, + 0xFC, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x00, + 0x00, 0x07, 0xFF, 0xBF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xF7, + 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFE, 0xFF, 0xFF, 0xC0, 0x00, + 0x00, 0x00, 0x07, 0xFF, 0xDF, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x00, 0xFF, + 0xF3, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFE, 0x7F, 0xFF, 0xE0, + 0x00, 0x00, 0x00, 0x07, 0xFF, 0xCF, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x00, + 0xFF, 0xF1, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x1F, 0xFE, 0x3F, 0xFF, + 0xF0, 0x00, 0x00, 0x00, 0x07, 0xFF, 0xC7, 0xFF, 0xFE, 0x00, 0x00, 0x00, + 0x00, 0xFF, 0xF8, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x1F, 0xFE, 0x1F, + 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x07, 0xFF, 0xC3, 0xFF, 0xFF, 0x00, 0x00, + 0x00, 0x00, 0xFF, 0xF8, 0x7F, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x1F, 0xFF, + 0x0F, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x07, 0xFF, 0xC1, 0xFF, 0xFF, 0x80, + 0x00, 0x00, 0x00, 0xFF, 0xF8, 0x3F, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x1F, + 0xFF, 0x07, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x07, 0xFF, 0xE0, 0xFF, 0xFF, + 0xC0, 0x00, 0x00, 0x00, 0xFF, 0xF8, 0x1F, 0xFF, 0xF8, 0x00, 0x00, 0x00, + 0x1F, 0xFF, 0x03, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x03, 0xFF, 0xE0, 0x7F, + 0xFF, 0xE0, 0x00, 0x00, 0x00, 0xFF, 0xFC, 0x0F, 0xFF, 0xFC, 0x00, 0x00, + 0x00, 0x1F, 0xFF, 0x01, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x03, 0xFF, 0xE0, + 0x3F, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, 0xFC, 0x07, 0xFF, 0xFE, 0x00, + 0x00, 0x00, 0x1F, 0xFF, 0x00, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x03, 0xFF, + 0xE0, 0x1F, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0xFF, 0xFC, 0x03, 0xFF, 0xFF, + 0x00, 0x00, 0x00, 0x1F, 0xFF, 0x80, 0x7F, 0xFF, 0xE0, 0x00, 0x00, 0x03, + 0xFF, 0xE0, 0x0F, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0xFF, 0xFC, 0x01, 0xFF, + 0xFF, 0x80, 0x00, 0x00, 0x1F, 0xFF, 0x80, 0x3F, 0xFF, 0xF0, 0x00, 0x00, + 0x03, 0xFF, 0xF0, 0x07, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x7F, 0xFC, 0x00, + 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x1F, 0xFF, 0x80, 0x1F, 0xFF, 0xF8, 0x00, + 0x00, 0x03, 0xFF, 0xF0, 0x03, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x7F, 0xFE, + 0x00, 0x7F, 0xFF, 0xE0, 0x00, 0x00, 0x1F, 0xFF, 0x80, 0x0F, 0xFF, 0xFC, + 0x00, 0x00, 0x03, 0xFF, 0xF0, 0x01, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x7F, + 0xFE, 0x00, 0x3F, 0xFF, 0xF0, 0x00, 0x00, 0x1F, 0xFF, 0x80, 0x07, 0xFF, + 0xFE, 0x00, 0x00, 0x03, 0xFF, 0xF0, 0x00, 0xFF, 0xFF, 0xC0, 0x00, 0x00, + 0x7F, 0xFE, 0x00, 0x1F, 0xFF, 0xF8, 0x00, 0x00, 0x0F, 0xFF, 0xC0, 0x03, + 0xFF, 0xFF, 0x00, 0x00, 0x03, 0xFF, 0xF0, 0x00, 0x7F, 0xFF, 0xE0, 0x00, + 0x00, 0x7F, 0xFE, 0x00, 0x0F, 0xFF, 0xFC, 0x00, 0x00, 0x0F, 0xFF, 0xC0, + 0x01, 0xFF, 0xFF, 0x80, 0x00, 0x03, 0xFF, 0xF8, 0x00, 0x3F, 0xFF, 0xF0, + 0x00, 0x00, 0x7F, 0xFE, 0x00, 0x07, 0xFF, 0xFE, 0x00, 0x00, 0x0F, 0xFF, + 0xC0, 0x00, 0xFF, 0xFF, 0xC0, 0x00, 0x03, 0xFF, 0xF8, 0x00, 0x1F, 0xFF, + 0xF8, 0x00, 0x00, 0x7F, 0xFF, 0x00, 0x03, 0xFF, 0xFF, 0x00, 0x00, 0x0F, + 0xFF, 0xC0, 0x00, 0x7F, 0xFF, 0xE0, 0x00, 0x03, 0xFF, 0xF8, 0x00, 0x0F, + 0xFF, 0xFC, 0x00, 0x00, 0x7F, 0xFF, 0x00, 0x01, 0xFF, 0xFF, 0x80, 0x00, + 0x0F, 0xFF, 0xC0, 0x00, 0x3F, 0xFF, 0xF0, 0x00, 0x01, 0xFF, 0xF8, 0x00, + 0x07, 0xFF, 0xFE, 0x00, 0x00, 0x7F, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xC0, + 0x00, 0x0F, 0xFF, 0xE0, 0x00, 0x1F, 0xFF, 0xF8, 0x00, 0x01, 0xFF, 0xF8, + 0x00, 0x03, 0xFF, 0xFF, 0x00, 0x00, 0x7F, 0xFF, 0x00, 0x00, 0x7F, 0xFF, + 0xE0, 0x00, 0x0F, 0xFF, 0xE0, 0x00, 0x0F, 0xFF, 0xFC, 0x00, 0x01, 0xFF, + 0xFC, 0x00, 0x01, 0xFF, 0xFF, 0x80, 0x00, 0x7F, 0xFF, 0x00, 0x00, 0x3F, + 0xFF, 0xF0, 0x00, 0x0F, 0xFF, 0xE0, 0x00, 0x07, 0xFF, 0xFE, 0x00, 0x01, + 0xFF, 0xFC, 0x00, 0x00, 0xFF, 0xFF, 0xC0, 0x00, 0x7F, 0xFF, 0x80, 0x00, + 0x1F, 0xFF, 0xF8, 0x00, 0x0F, 0xFF, 0xE0, 0x00, 0x03, 0xFF, 0xFF, 0x00, + 0x01, 0xFF, 0xFC, 0x00, 0x00, 0x7F, 0xFF, 0xE0, 0x00, 0x3F, 0xFF, 0x80, + 0x00, 0x0F, 0xFF, 0xFC, 0x00, 0x0F, 0xFF, 0xE0, 0x00, 0x01, 0xFF, 0xFF, + 0x80, 0x01, 0xFF, 0xFC, 0x00, 0x00, 0x3F, 0xFF, 0xF0, 0x00, 0x3F, 0xFF, + 0x80, 0x00, 0x07, 0xFF, 0xFE, 0x00, 0x0F, 0xFF, 0xF0, 0x00, 0x00, 0xFF, + 0xFF, 0xC0, 0x01, 0xFF, 0xFC, 0x00, 0x00, 0x1F, 0xFF, 0xF8, 0x00, 0x3F, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0x80, 0x00, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x7F, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFF, + 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0x80, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, + 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xC0, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x03, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xE0, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x01, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, + 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xFF, 0xFE, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, + 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x0F, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0x80, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x07, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, + 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xF8, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x03, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, + 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFC, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0x80, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xF0, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x7F, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, + 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xF0, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x7F, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xF0, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x7F, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xF0, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x7F, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xF0, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x7F, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, + 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xF0, 0x7F, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xE0, + 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x7F, + 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xE0, 0x00, 0x00, 0x00, + 0x00, 0x7F, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xE0, 0x00, + 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, + 0xE0, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x00, + 0x7F, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xE0, 0x00, 0x00, + 0x00, 0x00, 0x7F, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xE0, + 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x7F, + 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xE0, 0x00, 0x00, 0x00, + 0x00, 0x7F, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xE0, 0x00, + 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, + 0xE0, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x00, + 0x7F, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xE0, 0x00, 0x00, + 0x00, 0x00, 0x7F, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xE0, + 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xE0, 0x00, 0x60, 0x00, 0x00, 0x7F, + 0xFF, 0xE0, 0x1F, 0xFF, 0x00, 0x00, 0x7F, 0xFF, 0xE0, 0xFF, 0xFF, 0xE0, + 0x00, 0x7F, 0xFF, 0xE3, 0xFF, 0xFF, 0xF0, 0x00, 0x7F, 0xFF, 0xE7, 0xFF, + 0xFF, 0xFC, 0x00, 0x7F, 0xFF, 0xEF, 0xFF, 0xFF, 0xFE, 0x00, 0x7F, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, + 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xC0, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x7F, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xE0, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0x7F, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xF0, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x7F, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xF8, 0x7F, 0xFF, 0xFF, 0xC3, 0xFF, 0xFF, 0xF8, 0x7F, 0xFF, + 0xFE, 0x00, 0xFF, 0xFF, 0xF8, 0x7F, 0xFF, 0xFC, 0x00, 0x7F, 0xFF, 0xF8, + 0x7F, 0xFF, 0xF8, 0x00, 0x3F, 0xFF, 0xF8, 0x7F, 0xFF, 0xF8, 0x00, 0x1F, + 0xFF, 0xFC, 0x7F, 0xFF, 0xF0, 0x00, 0x1F, 0xFF, 0xFC, 0x7F, 0xFF, 0xF0, + 0x00, 0x1F, 0xFF, 0xFC, 0x7F, 0xFF, 0xE0, 0x00, 0x0F, 0xFF, 0xFC, 0x7F, + 0xFF, 0xE0, 0x00, 0x0F, 0xFF, 0xFC, 0x7F, 0xFF, 0xE0, 0x00, 0x0F, 0xFF, + 0xFC, 0x7F, 0xFF, 0xE0, 0x00, 0x0F, 0xFF, 0xFE, 0x7F, 0xFF, 0xE0, 0x00, + 0x0F, 0xFF, 0xFE, 0x7F, 0xFF, 0xC0, 0x00, 0x0F, 0xFF, 0xFE, 0x7F, 0xFF, + 0xC0, 0x00, 0x0F, 0xFF, 0xFE, 0x0F, 0xFF, 0xC0, 0x00, 0x0F, 0xFF, 0xFE, + 0x00, 0x00, 0xC0, 0x00, 0x0F, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x0F, + 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFE, 0x00, 0x00, 0x00, + 0x00, 0x0F, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFE, 0x00, + 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFF, + 0xFE, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, + 0x0F, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0x00, 0x00, + 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFF, + 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x0F, + 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0x00, 0x00, 0x00, + 0x00, 0x0F, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0x00, + 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFF, + 0xFF, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, + 0x0F, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0x00, 0x00, + 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFF, + 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x0F, + 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0x00, 0x00, 0x00, + 0x00, 0x0F, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, + 0xFF, 0xE0, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0x00, 0x0F, 0xFF, + 0xFF, 0xFF, 0xFF, 0xE0, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0x00, + 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, + 0xE0, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0x00, 0x0F, 0xFF, 0xFE, + 0xFF, 0xFF, 0xE0, 0x00, 0x0F, 0xFF, 0xFE, 0xFF, 0xFF, 0xE0, 0x00, 0x0F, + 0xFF, 0xFE, 0xFF, 0xFF, 0xE0, 0x00, 0x0F, 0xFF, 0xFE, 0xFF, 0xFF, 0xE0, + 0x00, 0x0F, 0xFF, 0xFE, 0xFF, 0xFF, 0xE0, 0x00, 0x0F, 0xFF, 0xFE, 0xFF, + 0xFF, 0xE0, 0x00, 0x0F, 0xFF, 0xFE, 0xFF, 0xFF, 0xE0, 0x00, 0x0F, 0xFF, + 0xFE, 0xFF, 0xFF, 0xE0, 0x00, 0x0F, 0xFF, 0xFE, 0xFF, 0xFF, 0xE0, 0x00, + 0x0F, 0xFF, 0xFE, 0xFF, 0xFF, 0xE0, 0x00, 0x0F, 0xFF, 0xFE, 0xFF, 0xFF, + 0xE0, 0x00, 0x0F, 0xFF, 0xFE, 0xFF, 0xFF, 0xE0, 0x00, 0x0F, 0xFF, 0xFE, + 0xFF, 0xFF, 0xE0, 0x00, 0x0F, 0xFF, 0xFE, 0xFF, 0xFF, 0xE0, 0x00, 0x0F, + 0xFF, 0xFE, 0xFF, 0xFF, 0xE0, 0x00, 0x0F, 0xFF, 0xFC, 0xFF, 0xFF, 0xE0, + 0x00, 0x0F, 0xFF, 0xFC, 0xFF, 0xFF, 0xE0, 0x00, 0x0F, 0xFF, 0xFC, 0xFF, + 0xFF, 0xF0, 0x00, 0x1F, 0xFF, 0xFC, 0xFF, 0xFF, 0xF0, 0x00, 0x1F, 0xFF, + 0xFC, 0xFF, 0xFF, 0xF0, 0x00, 0x1F, 0xFF, 0xFC, 0xFF, 0xFF, 0xF8, 0x00, + 0x3F, 0xFF, 0xF8, 0x7F, 0xFF, 0xF8, 0x00, 0x7F, 0xFF, 0xF8, 0x7F, 0xFF, + 0xFE, 0x00, 0xFF, 0xFF, 0xF8, 0x7F, 0xFF, 0xFF, 0x83, 0xFF, 0xFF, 0xF8, + 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xF0, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x1F, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xE0, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0x0F, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xC0, 0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x03, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFE, 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, + 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, + 0xE0, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x7F, + 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x01, 0xFF, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x01, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0xFC, + 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x3F, + 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, + 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x00, 0x00, 0x3F, 0xFF, 0xFF, + 0xFF, 0xFF, 0xC0, 0x00, 0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x00, 0x00, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0x00, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x00, 0x3F, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, + 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x0F, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFE, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0x0F, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x01, 0xFF, 0xFF, 0xFC, 0x07, 0xFF, + 0xFF, 0xF0, 0x1F, 0xFF, 0xFF, 0x00, 0x0F, 0xFF, 0xFF, 0x01, 0xFF, 0xFF, + 0xE0, 0x00, 0x7F, 0xFF, 0xF0, 0x3F, 0xFF, 0xFC, 0x00, 0x07, 0xFF, 0xFF, + 0x03, 0xFF, 0xFF, 0xC0, 0x00, 0x3F, 0xFF, 0xF0, 0x3F, 0xFF, 0xF8, 0x00, + 0x03, 0xFF, 0xFF, 0x83, 0xFF, 0xFF, 0x80, 0x00, 0x3F, 0xFF, 0xF8, 0x3F, + 0xFF, 0xF8, 0x00, 0x01, 0xFF, 0xFF, 0x87, 0xFF, 0xFF, 0x00, 0x00, 0x1F, + 0xFF, 0xF8, 0x7F, 0xFF, 0xF0, 0x00, 0x01, 0xFF, 0xFF, 0x87, 0xFF, 0xFF, + 0x00, 0x00, 0x1F, 0xFF, 0xF8, 0x7F, 0xFF, 0xF0, 0x00, 0x01, 0xFF, 0xFF, + 0x87, 0xFF, 0xFF, 0x00, 0x00, 0x1F, 0xFF, 0xF8, 0x7F, 0xFF, 0xF0, 0x00, + 0x01, 0xFF, 0xFF, 0xC7, 0xFF, 0xFF, 0x00, 0x00, 0x1F, 0xFF, 0xFC, 0xFF, + 0xFF, 0xF0, 0x00, 0x01, 0xFF, 0xFF, 0xCF, 0xFF, 0xFF, 0x00, 0x00, 0x1F, + 0xFF, 0xFC, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0xFF, 0xFF, 0xCF, 0xFF, 0xFF, + 0x00, 0x00, 0x0F, 0xFF, 0xFC, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0xFF, 0xFF, + 0xCF, 0xFF, 0xFE, 0x00, 0x00, 0x0F, 0xFF, 0xFC, 0xFF, 0xFF, 0xE0, 0x00, + 0x00, 0xFF, 0xFF, 0xCF, 0xFF, 0xFE, 0x00, 0x00, 0x0F, 0xFF, 0xFC, 0xFF, + 0xFF, 0xE0, 0x00, 0x00, 0xFF, 0xFF, 0xCF, 0xFF, 0xFE, 0x00, 0x00, 0x0F, + 0xFF, 0xFC, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0xFF, 0xFF, 0xCF, 0xFF, 0xFE, + 0x00, 0x00, 0x0F, 0xFF, 0xFC, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0xFF, 0xFF, + 0xCF, 0xFF, 0xFE, 0x00, 0x00, 0x0F, 0xFF, 0xFC, 0xFF, 0xFF, 0xE0, 0x00, + 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, + 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFE, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFE, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x00, + 0x0F, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xE0, 0x00, + 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, + 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFE, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xFF, 0xFF, 0xE0, 0x00, 0x3C, 0x00, 0x00, 0x0F, 0xFF, 0xFE, + 0x01, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xE0, 0x7F, 0xFF, 0xFC, 0x00, + 0x0F, 0xFF, 0xFE, 0x1F, 0xFF, 0xFF, 0xF0, 0x00, 0xFF, 0xFF, 0xE7, 0xFF, + 0xFF, 0xFF, 0xC0, 0x0F, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFE, 0x00, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0x80, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x0F, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, + 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x8F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xF8, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x8F, 0xFF, 0xFF, + 0xFE, 0x01, 0xFF, 0xFF, 0xFC, 0xFF, 0xFF, 0xFF, 0x00, 0x07, 0xFF, 0xFF, + 0xCF, 0xFF, 0xFF, 0xC0, 0x00, 0x3F, 0xFF, 0xFC, 0xFF, 0xFF, 0xF8, 0x00, + 0x01, 0xFF, 0xFF, 0xCF, 0xFF, 0xFF, 0x00, 0x00, 0x1F, 0xFF, 0xFE, 0xFF, + 0xFF, 0xE0, 0x00, 0x00, 0xFF, 0xFF, 0xEF, 0xFF, 0xFE, 0x00, 0x00, 0x0F, + 0xFF, 0xFE, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0xFF, 0xFF, 0xEF, 0xFF, 0xFE, + 0x00, 0x00, 0x07, 0xFF, 0xFE, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x7F, 0xFF, + 0xEF, 0xFF, 0xFE, 0x00, 0x00, 0x07, 0xFF, 0xFE, 0xFF, 0xFF, 0xE0, 0x00, + 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFE, 0x00, 0x00, 0x07, 0xFF, 0xFF, 0xFF, + 0xFF, 0xE0, 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFE, 0x00, 0x00, 0x07, + 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFE, + 0x00, 0x00, 0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x7F, 0xFF, + 0xFF, 0xFF, 0xFE, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0x00, + 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xFE, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xFF, + 0xFF, 0xE0, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xFE, 0x00, 0x00, 0x03, + 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xFE, + 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x3F, 0xFF, + 0xFF, 0xFF, 0xFE, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0x00, + 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xFE, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xFF, + 0xFF, 0xE0, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xFE, 0x00, 0x00, 0x03, + 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xFE, + 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x3F, 0xFF, + 0xFF, 0xFF, 0xFE, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0x00, + 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xFE, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xFF, + 0xFF, 0xE0, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xFE, 0x00, 0x00, 0x03, + 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xFE, + 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x3F, 0xFF, + 0xFF, 0xFF, 0xFE, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0x00, + 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xFE, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xFF, + 0xFF, 0xF0, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x03, + 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x7F, 0xFF, 0xF7, 0xFF, 0xFF, + 0x00, 0x00, 0x07, 0xFF, 0xFF, 0x7F, 0xFF, 0xF0, 0x00, 0x00, 0x7F, 0xFF, + 0xF7, 0xFF, 0xFF, 0x00, 0x00, 0x07, 0xFF, 0xFF, 0x7F, 0xFF, 0xF0, 0x00, + 0x00, 0x7F, 0xFF, 0xF7, 0xFF, 0xFF, 0x00, 0x00, 0x07, 0xFF, 0xFE, 0x7F, + 0xFF, 0xF8, 0x00, 0x00, 0x7F, 0xFF, 0xE7, 0xFF, 0xFF, 0x80, 0x00, 0x07, + 0xFF, 0xFE, 0x7F, 0xFF, 0xF8, 0x00, 0x00, 0xFF, 0xFF, 0xE3, 0xFF, 0xFF, + 0xC0, 0x00, 0x0F, 0xFF, 0xFE, 0x3F, 0xFF, 0xFC, 0x00, 0x00, 0xFF, 0xFF, + 0xE3, 0xFF, 0xFF, 0xE0, 0x00, 0x1F, 0xFF, 0xFC, 0x3F, 0xFF, 0xFE, 0x00, + 0x03, 0xFF, 0xFF, 0xC1, 0xFF, 0xFF, 0xF0, 0x00, 0x3F, 0xFF, 0xFC, 0x1F, + 0xFF, 0xFF, 0xC0, 0x0F, 0xFF, 0xFF, 0xC1, 0xFF, 0xFF, 0xFF, 0xDF, 0xFF, + 0xFF, 0xF8, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x07, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFE, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0x01, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0x80, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x00, 0x07, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, + 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x00, 0x07, 0xFF, 0xFF, + 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xFF, 0xFF, 0xE0, 0x00, 0x00, + 0x00, 0x7F, 0xFF, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFC, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xF0, 0x00, 0x00, 0x00, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0xE0, + 0x00, 0x00, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, + 0x0F, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xFE, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0xE0, 0x00, + 0x00, 0x00, 0x00, 0x07, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, 0x0F, + 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xFE, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, + 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0xC0, 0x00, 0x00, + 0x00, 0x00, 0x07, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFF, + 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xFC, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x7F, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, + 0xE0, 0x00, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x00, + 0x00, 0x07, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFE, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x7F, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xE0, + 0x00, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00, + 0x07, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFE, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x7F, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xF0, 0x00, + 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x07, + 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, + 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, + 0x00, 0x00, 0x01, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x03, 0xFF, + 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x1F, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, + 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, + 0x00, 0x01, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x03, 0xFF, 0xFF, + 0x80, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x1F, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xF8, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, + 0x01, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xC0, + 0x00, 0x00, 0x00, 0x00, 0x07, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x1F, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xFC, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x01, + 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xC0, 0x00, + 0x00, 0x00, 0x00, 0x07, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, 0x1F, + 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xFC, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, + 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xC0, 0x00, 0x00, + 0x00, 0x00, 0x07, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFF, + 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xFE, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x7F, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, + 0xF0, 0x00, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x00, + 0x00, 0x07, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFF, + 0x80, 0x00, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x3F, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xF8, + 0x00, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, + 0x03, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x07, 0xFF, 0xFF, 0x80, + 0x00, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x3F, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xFC, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x01, + 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x07, 0xFF, 0xFF, 0xC0, 0x00, + 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, 0x1F, + 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xFC, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x01, 0xFF, + 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xE0, 0x00, 0x00, + 0x00, 0x00, 0x07, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFF, + 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xFE, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x7F, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, + 0xF8, 0x00, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, + 0x00, 0x03, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFF, + 0xC0, 0x00, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x3F, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xFC, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x00, + 0x01, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x07, 0xFF, 0xFF, 0xE0, + 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, + 0x1F, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xFE, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xFF, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xF0, 0x00, + 0x00, 0x00, 0x00, 0x07, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x0F, + 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xFF, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, + 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xF8, 0x00, 0x00, + 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x07, 0xFF, + 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xC0, 0x00, 0x00, + 0x00, 0x00, 0x1F, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, + 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xFC, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xFF, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFF, + 0xF0, 0x00, 0x00, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x00, + 0x00, 0x07, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xFF, + 0x80, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x7F, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFC, + 0x00, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x00, + 0x03, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x07, 0xFF, 0xFF, 0xE0, + 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x01, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, + 0xFF, 0x80, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, + 0x07, 0xFF, 0xFF, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFC, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x0F, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, + 0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xF0, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x3F, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xF8, 0x0F, 0xFF, 0xFF, 0xC0, 0x0F, 0xFF, 0xFF, 0xC0, 0xFF, 0xFF, + 0xFC, 0x00, 0x3F, 0xFF, 0xFE, 0x07, 0xFF, 0xFF, 0xC0, 0x00, 0xFF, 0xFF, + 0xF8, 0x3F, 0xFF, 0xFC, 0x00, 0x03, 0xFF, 0xFF, 0xC1, 0xFF, 0xFF, 0xE0, + 0x00, 0x1F, 0xFF, 0xFE, 0x1F, 0xFF, 0xFE, 0x00, 0x00, 0x7F, 0xFF, 0xF0, + 0xFF, 0xFF, 0xF0, 0x00, 0x03, 0xFF, 0xFF, 0xC7, 0xFF, 0xFF, 0x80, 0x00, + 0x1F, 0xFF, 0xFE, 0x3F, 0xFF, 0xF8, 0x00, 0x00, 0xFF, 0xFF, 0xF1, 0xFF, + 0xFF, 0xC0, 0x00, 0x03, 0xFF, 0xFF, 0x9F, 0xFF, 0xFE, 0x00, 0x00, 0x1F, + 0xFF, 0xFC, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0xFF, 0xFF, 0xE7, 0xFF, 0xFF, + 0x80, 0x00, 0x07, 0xFF, 0xFF, 0x3F, 0xFF, 0xFC, 0x00, 0x00, 0x3F, 0xFF, + 0xF9, 0xFF, 0xFF, 0xE0, 0x00, 0x01, 0xFF, 0xFF, 0xEF, 0xFF, 0xFF, 0x00, + 0x00, 0x0F, 0xFF, 0xFF, 0x7F, 0xFF, 0xF8, 0x00, 0x00, 0x7F, 0xFF, 0xFB, + 0xFF, 0xFF, 0x80, 0x00, 0x03, 0xFF, 0xFF, 0xDF, 0xFF, 0xFC, 0x00, 0x00, + 0x1F, 0xFF, 0xFE, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0xFF, 0xFF, 0xF7, 0xFF, + 0xFF, 0x00, 0x00, 0x07, 0xFF, 0xFF, 0xBF, 0xFF, 0xF8, 0x00, 0x00, 0x3F, + 0xFF, 0xFD, 0xFF, 0xFF, 0xC0, 0x00, 0x01, 0xFF, 0xFF, 0xEF, 0xFF, 0xFE, + 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0x7F, 0xFF, 0xF0, 0x00, 0x00, 0x7F, 0xFF, + 0xFB, 0xFF, 0xFF, 0x80, 0x00, 0x03, 0xFF, 0xFF, 0xDF, 0xFF, 0xFC, 0x00, + 0x00, 0x1F, 0xFF, 0xFE, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0xFF, 0xFF, 0xF7, + 0xFF, 0xFF, 0x00, 0x00, 0x07, 0xFF, 0xFF, 0xBF, 0xFF, 0xFC, 0x00, 0x00, + 0x3F, 0xFF, 0xF9, 0xFF, 0xFF, 0xE0, 0x00, 0x01, 0xFF, 0xFF, 0xCF, 0xFF, + 0xFF, 0x00, 0x00, 0x0F, 0xFF, 0xFE, 0x3F, 0xFF, 0xF8, 0x00, 0x00, 0x7F, + 0xFF, 0xF1, 0xFF, 0xFF, 0xC0, 0x00, 0x03, 0xFF, 0xFF, 0x8F, 0xFF, 0xFE, + 0x00, 0x00, 0x1F, 0xFF, 0xFC, 0x7F, 0xFF, 0xF0, 0x00, 0x00, 0xFF, 0xFF, + 0xE3, 0xFF, 0xFF, 0x80, 0x00, 0x0F, 0xFF, 0xFE, 0x1F, 0xFF, 0xFC, 0x00, + 0x00, 0x7F, 0xFF, 0xF0, 0x7F, 0xFF, 0xE0, 0x00, 0x03, 0xFF, 0xFF, 0x83, + 0xFF, 0xFF, 0x80, 0x00, 0x1F, 0xFF, 0xFC, 0x1F, 0xFF, 0xFC, 0x00, 0x00, + 0xFF, 0xFF, 0xE0, 0x7F, 0xFF, 0xE0, 0x00, 0x0F, 0xFF, 0xFE, 0x03, 0xFF, + 0xFF, 0x00, 0x00, 0x7F, 0xFF, 0xF0, 0x1F, 0xFF, 0xFC, 0x00, 0x03, 0xFF, + 0xFF, 0x80, 0x7F, 0xFF, 0xE0, 0x00, 0x3F, 0xFF, 0xF8, 0x03, 0xFF, 0xFF, + 0x80, 0x01, 0xFF, 0xFF, 0xC0, 0x0F, 0xFF, 0xFC, 0x00, 0x1F, 0xFF, 0xFC, + 0x00, 0x7F, 0xFF, 0xF0, 0x01, 0xFF, 0xFF, 0xE0, 0x01, 0xFF, 0xFF, 0xE0, + 0x3F, 0xFF, 0xFE, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, + 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xF0, 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x0F, + 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, + 0x00, 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x00, 0x00, 0x1F, 0xFF, + 0xFF, 0xFF, 0xFF, 0xE0, 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, + 0x00, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x00, 0x01, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xF0, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xF8, 0x00, 0x7F, 0xFF, 0xFF, 0x0F, 0xFF, 0xFF, 0xE0, 0x07, 0xFF, + 0xFF, 0xE0, 0x1F, 0xFF, 0xFF, 0x00, 0x3F, 0xFF, 0xFE, 0x00, 0x7F, 0xFF, + 0xF8, 0x01, 0xFF, 0xFF, 0xE0, 0x01, 0xFF, 0xFF, 0xE0, 0x1F, 0xFF, 0xFE, + 0x00, 0x0F, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x3F, 0xFF, 0xF8, + 0x0F, 0xFF, 0xFF, 0x00, 0x01, 0xFF, 0xFF, 0xE0, 0x7F, 0xFF, 0xF8, 0x00, + 0x07, 0xFF, 0xFF, 0x03, 0xFF, 0xFF, 0x80, 0x00, 0x3F, 0xFF, 0xF8, 0x1F, + 0xFF, 0xFC, 0x00, 0x01, 0xFF, 0xFF, 0xE1, 0xFF, 0xFF, 0xE0, 0x00, 0x07, + 0xFF, 0xFF, 0x0F, 0xFF, 0xFE, 0x00, 0x00, 0x3F, 0xFF, 0xF8, 0x7F, 0xFF, + 0xF0, 0x00, 0x01, 0xFF, 0xFF, 0xC3, 0xFF, 0xFF, 0x80, 0x00, 0x0F, 0xFF, + 0xFF, 0x3F, 0xFF, 0xFC, 0x00, 0x00, 0x7F, 0xFF, 0xF9, 0xFF, 0xFF, 0xE0, + 0x00, 0x03, 0xFF, 0xFF, 0xCF, 0xFF, 0xFF, 0x00, 0x00, 0x0F, 0xFF, 0xFE, + 0x7F, 0xFF, 0xF8, 0x00, 0x00, 0x7F, 0xFF, 0xF3, 0xFF, 0xFF, 0x80, 0x00, + 0x03, 0xFF, 0xFF, 0x9F, 0xFF, 0xFC, 0x00, 0x00, 0x1F, 0xFF, 0xFD, 0xFF, + 0xFF, 0xE0, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x07, + 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, + 0xC0, 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x00, 0x00, 0x0F, 0xFF, + 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, + 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x00, 0x1F, 0xFF, 0xFF, + 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, + 0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, + 0xFF, 0xC0, 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x00, 0x00, 0x0F, + 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, + 0x80, 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x00, 0x1F, 0xFF, + 0xFF, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, + 0x00, 0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x00, 0x00, 0x3F, 0xFF, 0xFF, + 0xFF, 0xFF, 0xC0, 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x00, 0x00, + 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, + 0xFF, 0x80, 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x00, 0x1F, + 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0x00, 0x00, 0x07, 0xFF, 0xFF, 0xBF, 0xFF, 0xF8, 0x00, 0x00, 0x3F, 0xFF, + 0xFD, 0xFF, 0xFF, 0xE0, 0x00, 0x01, 0xFF, 0xFF, 0xCF, 0xFF, 0xFF, 0x00, + 0x00, 0x0F, 0xFF, 0xFE, 0x7F, 0xFF, 0xF8, 0x00, 0x00, 0xFF, 0xFF, 0xF3, + 0xFF, 0xFF, 0xC0, 0x00, 0x07, 0xFF, 0xFF, 0x9F, 0xFF, 0xFE, 0x00, 0x00, + 0x3F, 0xFF, 0xFC, 0x7F, 0xFF, 0xF0, 0x00, 0x01, 0xFF, 0xFF, 0xE3, 0xFF, + 0xFF, 0xC0, 0x00, 0x0F, 0xFF, 0xFE, 0x1F, 0xFF, 0xFE, 0x00, 0x00, 0xFF, + 0xFF, 0xF0, 0xFF, 0xFF, 0xF8, 0x00, 0x07, 0xFF, 0xFF, 0x83, 0xFF, 0xFF, + 0xE0, 0x00, 0x7F, 0xFF, 0xFC, 0x1F, 0xFF, 0xFF, 0x80, 0x07, 0xFF, 0xFF, + 0xC0, 0xFF, 0xFF, 0xFF, 0x81, 0xFF, 0xFF, 0xFE, 0x03, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xF0, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, + 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0x80, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x7F, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFC, 0x00, 0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0x00, 0x1F, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFE, 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, + 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x00, 0x00, 0x07, 0xFF, 0xFF, + 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x1F, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x00, + 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xFF, + 0xF0, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x0F, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xFF, 0xFC, 0x00, + 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x07, 0xFF, + 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xFE, 0x00, 0x00, + 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, + 0xFF, 0x00, 0x00, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x07, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, + 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xE0, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x00, 0x7F, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFC, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xF8, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x03, + 0xFF, 0xFF, 0xF8, 0x1F, 0xFF, 0xFF, 0xE0, 0xFF, 0xFF, 0xFC, 0x00, 0x7F, + 0xFF, 0xFE, 0x1F, 0xFF, 0xFE, 0x00, 0x07, 0xFF, 0xFF, 0xC3, 0xFF, 0xFF, + 0xC0, 0x00, 0x7F, 0xFF, 0xF8, 0x7F, 0xFF, 0xF0, 0x00, 0x0F, 0xFF, 0xFF, + 0x1F, 0xFF, 0xFC, 0x00, 0x00, 0xFF, 0xFF, 0xF3, 0xFF, 0xFF, 0x80, 0x00, + 0x1F, 0xFF, 0xFE, 0x7F, 0xFF, 0xF0, 0x00, 0x03, 0xFF, 0xFF, 0xCF, 0xFF, + 0xFE, 0x00, 0x00, 0x3F, 0xFF, 0xF9, 0xFF, 0xFF, 0x80, 0x00, 0x07, 0xFF, + 0xFF, 0x3F, 0xFF, 0xF0, 0x00, 0x00, 0xFF, 0xFF, 0xEF, 0xFF, 0xFE, 0x00, + 0x00, 0x1F, 0xFF, 0xFD, 0xFF, 0xFF, 0xC0, 0x00, 0x03, 0xFF, 0xFF, 0xFF, + 0xFF, 0xF8, 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x0F, + 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, + 0x00, 0x00, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x03, 0xFF, 0xFF, + 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x00, + 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, + 0xF0, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xFE, 0x00, 0x00, 0x07, 0xFF, + 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x00, + 0x00, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xFF, + 0xFF, 0xE0, 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x00, 0x0F, + 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, + 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xFE, 0x00, 0x00, 0x07, 0xFF, 0xFF, + 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x00, 0x00, + 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, + 0xE0, 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x00, 0x0F, 0xFF, + 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, + 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xFE, 0x00, 0x00, 0x07, 0xFF, 0xFF, 0xFF, + 0xFF, 0xC0, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x00, 0x00, 0x1F, + 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, + 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x00, 0x0F, 0xFF, 0xFF, + 0xFF, 0xFF, 0x80, 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x00, 0x00, + 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x07, 0xFF, 0xFF, 0xFF, 0xFF, + 0xE0, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x00, 0x1F, 0xFF, + 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, + 0x00, 0x7F, 0xFF, 0xF7, 0xFF, 0xFE, 0x00, 0x00, 0x0F, 0xFF, 0xFE, 0xFF, + 0xFF, 0xC0, 0x00, 0x01, 0xFF, 0xFF, 0xDF, 0xFF, 0xF8, 0x00, 0x00, 0x3F, + 0xFF, 0xFB, 0xFF, 0xFF, 0x80, 0x00, 0x07, 0xFF, 0xFF, 0x7F, 0xFF, 0xF0, + 0x00, 0x00, 0xFF, 0xFF, 0xEF, 0xFF, 0xFE, 0x00, 0x00, 0x1F, 0xFF, 0xFD, + 0xFF, 0xFF, 0xC0, 0x00, 0x03, 0xFF, 0xFF, 0x9F, 0xFF, 0xFC, 0x00, 0x00, + 0x7F, 0xFF, 0xF3, 0xFF, 0xFF, 0xC0, 0x00, 0x1F, 0xFF, 0xFE, 0x7F, 0xFF, + 0xF8, 0x00, 0x07, 0xFF, 0xFF, 0xCF, 0xFF, 0xFF, 0xC0, 0x03, 0xFF, 0xFF, + 0xF8, 0xFF, 0xFF, 0xFE, 0x03, 0xFF, 0xFF, 0xFF, 0x1F, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xE3, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x3F, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x87, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xF0, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x0F, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, + 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xE0, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x01, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xF0, 0x00, 0xFF, 0xFF, 0xFF, 0xEF, 0xFF, 0xFE, 0x00, 0x07, 0xFF, 0xFF, + 0xF1, 0xFF, 0xFF, 0xC0, 0x00, 0x3F, 0xFF, 0xF8, 0x3F, 0xFF, 0xF8, 0x00, + 0x00, 0x7F, 0xF0, 0x07, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, + 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xFC, 0x00, 0x00, 0x00, + 0x00, 0x03, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xF0, + 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x01, + 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xF8, 0x00, 0x00, + 0x00, 0x00, 0x07, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, + 0xE0, 0x00, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x00, + 0x03, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xF0, 0x00, + 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFE, 0x7F, 0xFF, 0xE0, 0x00, 0x01, 0xFF, + 0xFF, 0xCF, 0xFF, 0xFC, 0x00, 0x00, 0x3F, 0xFF, 0xF9, 0xFF, 0xFF, 0x80, + 0x00, 0x07, 0xFF, 0xFF, 0x3F, 0xFF, 0xF0, 0x00, 0x00, 0xFF, 0xFF, 0xE7, + 0xFF, 0xFE, 0x00, 0x00, 0x1F, 0xFF, 0xFC, 0xFF, 0xFF, 0xC0, 0x00, 0x03, + 0xFF, 0xFF, 0x9F, 0xFF, 0xF8, 0x00, 0x00, 0x7F, 0xFF, 0xF3, 0xFF, 0xFF, + 0x00, 0x00, 0x0F, 0xFF, 0xFE, 0x7F, 0xFF, 0xE0, 0x00, 0x01, 0xFF, 0xFF, + 0xCF, 0xFF, 0xFC, 0x00, 0x00, 0x3F, 0xFF, 0xF9, 0xFF, 0xFF, 0x80, 0x00, + 0x07, 0xFF, 0xFF, 0x3F, 0xFF, 0xF0, 0x00, 0x00, 0xFF, 0xFF, 0xE7, 0xFF, + 0xFE, 0x00, 0x00, 0x1F, 0xFF, 0xFC, 0xFF, 0xFF, 0xC0, 0x00, 0x03, 0xFF, + 0xFF, 0x9F, 0xFF, 0xF8, 0x00, 0x00, 0x7F, 0xFF, 0xF3, 0xFF, 0xFF, 0x00, + 0x00, 0x0F, 0xFF, 0xFC, 0x7F, 0xFF, 0xF0, 0x00, 0x03, 0xFF, 0xFF, 0x8F, + 0xFF, 0xFE, 0x00, 0x00, 0x7F, 0xFF, 0xF1, 0xFF, 0xFF, 0xC0, 0x00, 0x0F, + 0xFF, 0xFE, 0x3F, 0xFF, 0xF8, 0x00, 0x01, 0xFF, 0xFF, 0xC3, 0xFF, 0xFF, + 0x00, 0x00, 0x3F, 0xFF, 0xF8, 0x7F, 0xFF, 0xE0, 0x00, 0x07, 0xFF, 0xFF, + 0x0F, 0xFF, 0xFE, 0x00, 0x00, 0xFF, 0xFF, 0xC1, 0xFF, 0xFF, 0xC0, 0x00, + 0x3F, 0xFF, 0xF8, 0x3F, 0xFF, 0xF8, 0x00, 0x07, 0xFF, 0xFF, 0x07, 0xFF, + 0xFF, 0x80, 0x01, 0xFF, 0xFF, 0xE0, 0x7F, 0xFF, 0xF8, 0x00, 0x3F, 0xFF, + 0xF8, 0x0F, 0xFF, 0xFF, 0x80, 0x0F, 0xFF, 0xFF, 0x01, 0xFF, 0xFF, 0xFF, + 0x0F, 0xFF, 0xFF, 0xE0, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x03, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xE0, 0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x00, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, + 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x1F, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFE, 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x1F, + 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, + 0x00, 0x00, 0x1F, 0xFF, 0xFF, 0xFF, 0xFE, 0x00, 0x00, 0x01, 0xFF, 0xFF, + 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0x00, + 0x00, 0x7F, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xE0, + 0x00, 0x00, 0x00, 0x00, 0x03, 0xFE, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xF8, 0xFF, 0xFF, 0xFB, 0xFF, 0xFF, 0xEF, 0xFF, 0xFF, + 0xBF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFB, 0xFF, 0xFF, 0xEF, 0xFF, 0xFF, 0xBF, + 0xFF, 0xFE, 0xFF, 0xFF, 0xFB, 0xFF, 0xFF, 0xEF, 0xFF, 0xFF, 0xBF, 0xFF, + 0xFE, 0xFF, 0xFF, 0xFB, 0xFF, 0xFF, 0xEF, 0xFF, 0xFF, 0xBF, 0xFF, 0xFE, + 0xFF, 0xFF, 0xFB, 0xFF, 0xFF, 0xEF, 0xFF, 0xFF, 0xBF, 0xFF, 0xFE, 0xFF, + 0xFF, 0xFB, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x03, 0xFF, 0xF0, + 0x0F, 0xFF, 0x80, 0x3F, 0xFE, 0x01, 0xFF, 0xF8, 0x07, 0xFF, 0xC0, 0x1F, + 0xFF, 0x00, 0x7F, 0xFC, 0x03, 0xFF, 0xF0, 0x0F, 0xFF, 0x80, 0x3F, 0xFE, + 0x00, 0xFF, 0xF8, 0x03, 0xFF, 0xC0, 0x1F, 0xFF, 0x00, 0x7F, 0xFC, 0x01, + 0xFF, 0xF0, 0x07, 0xFF, 0x80, 0x1F, 0xFE, 0x00, 0xFF, 0xF8, 0x03, 0xFF, + 0xC0, 0x0F, 0xFF, 0x00, 0x3F, 0xFC, 0x01, 0xFF, 0xF0, 0x07, 0xFF, 0x80, + 0x1F, 0xFE, 0x00, 0x7F, 0xF8, 0x01, 0xFF, 0xC0, 0x0F, 0xFF, 0x00, 0x3F, + 0xFC, 0x00, 0xFF, 0xE0, 0x03, 0xFF, 0x80, 0x1F, 0xFE, 0x00, 0x7F, 0xF8, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0x00, 0x00, 0x00, 0x00, + 0x01, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x01, 0xF8, 0x00, 0x00, 0x00, 0x00, + 0x03, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x03, 0xFE, 0x00, 0x00, 0x00, 0x00, + 0x07, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0x80, 0x00, 0x00, 0x00, + 0x0F, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xE0, 0x00, 0x00, 0x00, + 0x1F, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xF8, 0x00, 0x00, 0x00, + 0x3F, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xFE, 0x00, 0x00, 0x00, + 0x7F, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x00, + 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0xE0, 0x00, 0x01, + 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xF8, 0x00, 0x03, + 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x07, 0xFF, 0xFF, 0xFF, 0xF8, 0x00, 0x0F, + 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x1F, + 0xFF, 0xFF, 0xFF, 0xE0, 0x00, 0x1F, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0x3F, + 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x7F, + 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xFF, + 0xFF, 0xFF, 0xFE, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFE, 0x00, 0x00, 0x7F, + 0xFF, 0xFF, 0xFC, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xF8, 0x00, 0x00, 0x1F, + 0xFF, 0xFF, 0xF8, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x07, + 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x01, + 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00, + 0x7F, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0x00, 0x00, 0x00, 0x00, + 0x1F, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xE0, 0x00, 0x00, 0x00, + 0x07, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0x80, 0x00, 0x00, + 0x01, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFC, 0x00, 0x00, + 0x00, 0x7F, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xE0, 0x00, + 0x00, 0x1F, 0xFF, 0xFF, 0xF8, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0x00, + 0x00, 0x07, 0xFF, 0xFF, 0xFF, 0xE0, 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0xF8, + 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, + 0xC0, 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xF8, 0x00, 0x00, 0x7F, 0xFF, 0xFF, + 0xFF, 0x00, 0x00, 0x1F, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0x03, 0xFF, 0xFF, + 0xFF, 0xF8, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFE, 0x00, 0x00, 0x1F, 0xFF, + 0xFF, 0xFF, 0xC0, 0x00, 0x07, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0xFF, + 0xFF, 0xFF, 0xFE, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0x07, + 0xFF, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x00, + 0x3F, 0xFF, 0xFF, 0xF8, 0x00, 0x00, 0x07, 0xFF, 0xFF, 0xFC, 0x00, 0x00, + 0x01, 0xFF, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0x00, 0x00, + 0x00, 0x0F, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0xC0, 0x00, + 0x00, 0x00, 0x7F, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xF0, 0x00, + 0x00, 0x00, 0x03, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFC, 0x00, + 0x00, 0x00, 0x00, 0x1F, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x03, 0xFF, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, 0x1F, 0xC0, + 0x00, 0x00, 0x00, 0x00, 0x07, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1E, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x0F, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x07, 0xF0, 0x00, 0x00, 0x00, 0x00, + 0x03, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xC0, 0x00, 0x00, 0x00, + 0x00, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFE, 0x00, 0x00, 0x00, + 0x00, 0x3F, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xF0, 0x00, 0x00, + 0x00, 0x0F, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x07, 0xFF, 0xFF, 0x80, 0x00, + 0x00, 0x03, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0xFC, 0x00, + 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xE0, + 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xF8, 0x00, 0x00, 0x1F, 0xFF, 0xFF, 0xFF, + 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0x07, 0xFF, 0xFF, 0xFF, + 0xF8, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFE, 0x00, 0x00, 0x1F, 0xFF, 0xFF, + 0xFF, 0xC0, 0x00, 0x07, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0xFF, 0xFF, + 0xFF, 0xFE, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x07, 0xFF, + 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFE, 0x00, 0x00, 0x3F, + 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x07, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x01, + 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0x80, 0x00, + 0x07, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0xE0, 0x00, + 0x00, 0x3F, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xF8, 0x00, + 0x00, 0x01, 0xFF, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xFE, 0x00, + 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0x80, + 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xE0, + 0x00, 0x00, 0x00, 0x03, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x03, 0xFF, 0xF8, + 0x00, 0x00, 0x00, 0x07, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x07, 0xFF, 0xFE, + 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xFF, + 0x80, 0x00, 0x00, 0x1F, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x3F, 0xFF, 0xFF, + 0xE0, 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x7F, 0xFF, 0xFF, + 0xF8, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x01, 0xFF, 0xFF, 0xFF, + 0xFC, 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x03, 0xFF, 0xFF, 0xFF, + 0xF8, 0x00, 0x07, 0xFF, 0xFF, 0xFF, 0xF8, 0x00, 0x07, 0xFF, 0xFF, 0xFF, + 0xF0, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xE0, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, + 0xE0, 0x00, 0x1F, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, + 0xC0, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, + 0x80, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, + 0x00, 0x00, 0x1F, 0xFF, 0xFF, 0xFE, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xFE, + 0x00, 0x00, 0x07, 0xFF, 0xFF, 0xFC, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xFC, + 0x00, 0x00, 0x01, 0xFF, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xF8, + 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xF0, + 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xC0, + 0x00, 0x00, 0x00, 0x07, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x03, 0xFF, 0x80, + 0x00, 0x00, 0x00, 0x01, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x7F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3E, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x1E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x1F, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xF8, 0x00, + 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xFC, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xFF, + 0xF8, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xF8, 0x00, 0x01, 0xFF, 0xFF, + 0xFF, 0xFF, 0xF0, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0x00, 0x7F, + 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, + 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFC, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x0F, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xE0, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x81, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFE, 0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x1F, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0xFF, 0xFF, 0xFC, 0x0F, 0xFF, 0xFF, + 0xC3, 0xFF, 0xFF, 0xC0, 0x0F, 0xFF, 0xFF, 0x0F, 0xFF, 0xFF, 0x00, 0x1F, + 0xFF, 0xFE, 0x3F, 0xFF, 0xF8, 0x00, 0x7F, 0xFF, 0xF9, 0xFF, 0xFF, 0xE0, + 0x01, 0xFF, 0xFF, 0xE7, 0xFF, 0xFF, 0x80, 0x07, 0xFF, 0xFF, 0x9F, 0xFF, + 0xFC, 0x00, 0x0F, 0xFF, 0xFE, 0x7F, 0xFF, 0xF0, 0x00, 0x3F, 0xFF, 0xF9, + 0xFF, 0xFF, 0xC0, 0x00, 0xFF, 0xFF, 0xE7, 0xFF, 0xFF, 0x00, 0x03, 0xFF, + 0xFF, 0x9F, 0xFF, 0xFC, 0x00, 0x0F, 0xFF, 0xFF, 0x7F, 0xFF, 0xF0, 0x00, + 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, + 0xFF, 0xF0, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x0F, + 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, + 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFC, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x3F, 0xFF, 0xFF, + 0xFF, 0xFF, 0xC0, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x03, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, + 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, + 0xFF, 0xF0, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x0F, + 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x3F, 0xFF, 0xFC, 0x00, 0x00, 0x00, + 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xC0, 0x00, + 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xF8, + 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x07, 0xFF, + 0xFF, 0x80, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x00, + 0x7F, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0xE0, 0x00, 0x00, + 0x00, 0x07, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xFE, 0x00, + 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x03, 0xFF, 0xFF, + 0xC0, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x7F, + 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, + 0x0F, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xFE, 0x00, 0x00, + 0x00, 0x01, 0xFF, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x07, 0xFF, 0xFF, 0xC0, + 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFF, + 0xFC, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x7F, + 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x07, 0xFF, 0xFF, 0xFC, 0x00, 0x00, 0x00, + 0x3F, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0x80, 0x00, + 0x00, 0x3F, 0xFF, 0xFF, 0xFC, 0x00, 0x00, 0x07, 0xFF, 0xFF, 0xFF, 0xF0, + 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, + 0xFC, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0xFF, 0xFF, + 0xFF, 0xFF, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x0F, + 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xF8, 0x00, 0x00, + 0x00, 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xF8, 0x00, + 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xE0, + 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x03, 0xFF, + 0xFE, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x00, + 0x3F, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x80, 0x00, 0x00, + 0x00, 0x03, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xF8, 0x00, + 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, + 0x80, 0x00, 0x00, 0x00, 0x03, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x0F, + 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xE0, 0x00, 0x00, 0x00, + 0x00, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x03, 0xFF, 0xFE, 0x00, 0x00, + 0x00, 0x00, 0x0F, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xE0, + 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x00, + 0x3F, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xC0, 0x00, 0x00, + 0x00, 0x03, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFC, 0x00, + 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, + 0xC0, 0x00, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x0F, + 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xF0, 0x00, 0x00, 0x00, + 0x00, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0x00, 0x00, + 0x00, 0x00, 0x0F, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xF0, + 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x03, 0xFF, + 0xFF, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x00, + 0x3F, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xC0, 0x00, 0x00, + 0x00, 0x03, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFC, 0x00, + 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, + 0xC0, 0x00, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x0F, + 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xF0, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xE0, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xFE, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xFF, 0xFF, 0xFF, + 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x01, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, + 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xE0, 0x01, 0xFF, 0xFF, 0xFF, 0xE0, 0x00, + 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x3F, 0xFF, 0xFF, + 0xC0, 0x00, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x1F, + 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xFF, 0xC0, 0x00, 0x00, + 0x00, 0x0F, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFC, 0x00, + 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x07, 0xFF, 0xFF, + 0xC0, 0x00, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x3F, + 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xF0, 0x00, 0x00, + 0x01, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xC0, + 0x00, 0x00, 0x07, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, + 0xFF, 0x80, 0x00, 0x00, 0x3F, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xFF, 0xFE, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x03, 0xFF, 0xFC, 0x00, 0x00, 0x07, 0xFF, 0xFE, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x07, 0xFF, 0xF8, 0x00, 0x00, 0x3F, 0xFF, 0xF0, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xE0, 0x00, 0x01, 0xFF, + 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0x80, 0x00, + 0x07, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, + 0x00, 0x00, 0x3F, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xFF, 0xFC, 0x00, 0x00, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x01, 0xFF, 0xF8, 0x00, 0x07, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x07, 0xFF, 0xE0, 0x00, 0x1F, 0xFF, 0xF0, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xC0, 0x00, 0xFF, 0xFF, 0x80, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0x00, 0x03, 0xFF, + 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFC, 0x00, + 0x0F, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xFF, + 0xF8, 0x00, 0x7F, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x1F, 0xC0, 0x00, 0x00, + 0x07, 0xFF, 0xE0, 0x01, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xF8, + 0x00, 0x00, 0x0F, 0xFF, 0x80, 0x0F, 0xFF, 0xF0, 0x00, 0x00, 0x03, 0xFF, + 0xFF, 0xFE, 0x00, 0x00, 0x3F, 0xFE, 0x00, 0x3F, 0xFF, 0xC0, 0x00, 0x00, + 0x3F, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFC, 0x00, 0xFF, 0xFF, 0x00, + 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x01, 0xFF, 0xF0, 0x07, 0xFF, + 0xF8, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x07, 0xFF, 0xC0, + 0x1F, 0xFF, 0xE0, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x00, 0x1F, + 0xFF, 0x80, 0x7F, 0xFF, 0x80, 0x00, 0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, + 0x00, 0x3F, 0xFE, 0x01, 0xFF, 0xFC, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, + 0xFF, 0xE0, 0x00, 0xFF, 0xF8, 0x0F, 0xFF, 0xF0, 0x00, 0x00, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0x80, 0x03, 0xFF, 0xE0, 0x3F, 0xFF, 0xC0, 0x00, 0x07, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x00, 0x0F, 0xFF, 0x80, 0xFF, 0xFE, 0x00, + 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x00, 0x3F, 0xFF, 0x03, 0xFF, + 0xF8, 0x00, 0x01, 0xFF, 0xFF, 0x80, 0x1F, 0xFF, 0xE0, 0x00, 0x7F, 0xFC, + 0x1F, 0xFF, 0xE0, 0x00, 0x07, 0xFF, 0xF8, 0x00, 0x0F, 0xFF, 0x80, 0x01, + 0xFF, 0xF0, 0x7F, 0xFF, 0x80, 0x00, 0x3F, 0xFF, 0xC0, 0x00, 0x3F, 0xFE, + 0x00, 0x07, 0xFF, 0xC1, 0xFF, 0xFE, 0x00, 0x00, 0xFF, 0xFC, 0x00, 0x00, + 0xFF, 0xF8, 0x00, 0x1F, 0xFF, 0x07, 0xFF, 0xF0, 0x00, 0x07, 0xFF, 0xF0, + 0x00, 0x03, 0xFF, 0xE0, 0x00, 0x7F, 0xFC, 0x1F, 0xFF, 0xC0, 0x00, 0x1F, + 0xFF, 0x80, 0x00, 0x0F, 0xFF, 0x80, 0x01, 0xFF, 0xF8, 0xFF, 0xFF, 0x00, + 0x00, 0xFF, 0xFC, 0x00, 0x00, 0x3F, 0xFE, 0x00, 0x07, 0xFF, 0xE3, 0xFF, + 0xFC, 0x00, 0x03, 0xFF, 0xF0, 0x00, 0x00, 0xFF, 0xF8, 0x00, 0x0F, 0xFF, + 0x8F, 0xFF, 0xF0, 0x00, 0x0F, 0xFF, 0x80, 0x00, 0x03, 0xFF, 0xE0, 0x00, + 0x3F, 0xFE, 0x3F, 0xFF, 0x80, 0x00, 0x7F, 0xFE, 0x00, 0x00, 0x0F, 0xFF, + 0x80, 0x00, 0xFF, 0xF8, 0xFF, 0xFE, 0x00, 0x01, 0xFF, 0xF0, 0x00, 0x00, + 0x3F, 0xFE, 0x00, 0x03, 0xFF, 0xE3, 0xFF, 0xF8, 0x00, 0x07, 0xFF, 0xC0, + 0x00, 0x00, 0xFF, 0xF8, 0x00, 0x0F, 0xFF, 0x9F, 0xFF, 0xE0, 0x00, 0x3F, + 0xFF, 0x00, 0x00, 0x03, 0xFF, 0xE0, 0x00, 0x3F, 0xFE, 0x7F, 0xFF, 0x80, + 0x00, 0xFF, 0xF8, 0x00, 0x00, 0x0F, 0xFF, 0x80, 0x00, 0xFF, 0xF9, 0xFF, + 0xFE, 0x00, 0x03, 0xFF, 0xE0, 0x00, 0x00, 0x3F, 0xFE, 0x00, 0x03, 0xFF, + 0xF7, 0xFF, 0xF8, 0x00, 0x0F, 0xFF, 0x80, 0x00, 0x00, 0xFF, 0xF8, 0x00, + 0x0F, 0xFF, 0xDF, 0xFF, 0xC0, 0x00, 0x7F, 0xFE, 0x00, 0x00, 0x03, 0xFF, + 0xE0, 0x00, 0x3F, 0xFF, 0x7F, 0xFF, 0x00, 0x01, 0xFF, 0xF8, 0x00, 0x00, + 0x0F, 0xFF, 0x80, 0x00, 0xFF, 0xFD, 0xFF, 0xFC, 0x00, 0x07, 0xFF, 0xC0, + 0x00, 0x00, 0x3F, 0xFE, 0x00, 0x03, 0xFF, 0xF7, 0xFF, 0xF0, 0x00, 0x1F, + 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xF8, 0x00, 0x0F, 0xFF, 0xDF, 0xFF, 0xC0, + 0x00, 0x7F, 0xFC, 0x00, 0x00, 0x03, 0xFF, 0xE0, 0x00, 0x3F, 0xFF, 0x7F, + 0xFF, 0x00, 0x01, 0xFF, 0xF0, 0x00, 0x00, 0x0F, 0xFF, 0x80, 0x00, 0xFF, + 0xFF, 0xFF, 0xFC, 0x00, 0x0F, 0xFF, 0xC0, 0x00, 0x00, 0x3F, 0xFE, 0x00, + 0x01, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x3F, 0xFF, 0x00, 0x00, 0x00, 0xFF, + 0xF8, 0x00, 0x07, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0xFF, 0xFC, 0x00, 0x00, + 0x03, 0xFF, 0xE0, 0x00, 0x1F, 0xFF, 0xFF, 0xFF, 0x00, 0x03, 0xFF, 0xE0, + 0x00, 0x00, 0x0F, 0xFF, 0x80, 0x00, 0x7F, 0xFF, 0xFF, 0xFC, 0x00, 0x0F, + 0xFF, 0x80, 0x00, 0x00, 0x3F, 0xFE, 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0xF0, + 0x00, 0x3F, 0xFE, 0x00, 0x00, 0x00, 0xFF, 0xF8, 0x00, 0x07, 0xFF, 0xFF, + 0xFF, 0xC0, 0x00, 0xFF, 0xF8, 0x00, 0x00, 0x03, 0xFF, 0xE0, 0x00, 0x1F, + 0xFF, 0xFF, 0xFF, 0x00, 0x03, 0xFF, 0xE0, 0x00, 0x00, 0x0F, 0xFF, 0x80, + 0x00, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x0F, 0xFF, 0x80, 0x00, 0x00, 0x3F, + 0xFE, 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x3F, 0xFE, 0x00, 0x00, + 0x00, 0xFF, 0xF8, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0xFF, 0xF8, + 0x00, 0x00, 0x03, 0xFF, 0xE0, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0x00, 0x03, + 0xFF, 0xE0, 0x00, 0x00, 0x0F, 0xFF, 0x80, 0x00, 0xFF, 0xFF, 0xFF, 0xFC, + 0x00, 0x0F, 0xFF, 0x80, 0x00, 0x00, 0x3F, 0xFE, 0x00, 0x03, 0xFF, 0xFF, + 0xFF, 0xF0, 0x00, 0x3F, 0xFE, 0x00, 0x00, 0x00, 0xFF, 0xF8, 0x00, 0x0F, + 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0xFF, 0xF8, 0x00, 0x00, 0x03, 0xFF, 0xE0, + 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0x00, 0x03, 0xFF, 0xE0, 0x00, 0x00, 0x0F, + 0xFF, 0x80, 0x00, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x0F, 0xFF, 0x80, 0x00, + 0x00, 0x3F, 0xFE, 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x3F, 0xFE, + 0x00, 0x00, 0x00, 0xFF, 0xF8, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, + 0xFF, 0xF8, 0x00, 0x00, 0x03, 0xFF, 0xE0, 0x00, 0x3F, 0xFE, 0xFF, 0xFF, + 0x00, 0x03, 0xFF, 0xE0, 0x00, 0x00, 0x0F, 0xFF, 0x80, 0x00, 0xFF, 0xFB, + 0xFF, 0xFC, 0x00, 0x0F, 0xFF, 0x80, 0x00, 0x00, 0x3F, 0xFE, 0x00, 0x03, + 0xFF, 0xEF, 0xFF, 0xF0, 0x00, 0x3F, 0xFE, 0x00, 0x00, 0x00, 0xFF, 0xF8, + 0x00, 0x0F, 0xFF, 0xBF, 0xFF, 0xC0, 0x00, 0xFF, 0xF8, 0x00, 0x00, 0x03, + 0xFF, 0xE0, 0x00, 0x3F, 0xFE, 0x7F, 0xFF, 0x00, 0x03, 0xFF, 0xE0, 0x00, + 0x00, 0x0F, 0xFF, 0x80, 0x00, 0xFF, 0xF9, 0xFF, 0xFC, 0x00, 0x0F, 0xFF, + 0xC0, 0x00, 0x00, 0x3F, 0xFE, 0x00, 0x03, 0xFF, 0xE7, 0xFF, 0xF0, 0x00, + 0x3F, 0xFF, 0x00, 0x00, 0x01, 0xFF, 0xF8, 0x00, 0x1F, 0xFF, 0x1F, 0xFF, + 0xC0, 0x00, 0xFF, 0xFC, 0x00, 0x00, 0x07, 0xFF, 0xE0, 0x00, 0x7F, 0xFC, + 0x7F, 0xFF, 0x00, 0x03, 0xFF, 0xF0, 0x00, 0x00, 0x1F, 0xFF, 0x80, 0x01, + 0xFF, 0xF1, 0xFF, 0xFC, 0x00, 0x07, 0xFF, 0xC0, 0x00, 0x00, 0x7F, 0xFE, + 0x00, 0x07, 0xFF, 0xC7, 0xFF, 0xF8, 0x00, 0x1F, 0xFF, 0x00, 0x00, 0x01, + 0xFF, 0xF8, 0x00, 0x1F, 0xFF, 0x1F, 0xFF, 0xE0, 0x00, 0x7F, 0xFC, 0x00, + 0x00, 0x0F, 0xFF, 0xF0, 0x00, 0x7F, 0xF8, 0x7F, 0xFF, 0x80, 0x01, 0xFF, + 0xF8, 0x00, 0x00, 0x3F, 0xFF, 0xC0, 0x03, 0xFF, 0xE0, 0xFF, 0xFE, 0x00, + 0x07, 0xFF, 0xE0, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x0F, 0xFF, 0x83, 0xFF, + 0xF8, 0x00, 0x0F, 0xFF, 0x80, 0x00, 0x07, 0xFF, 0xFC, 0x00, 0x3F, 0xFE, + 0x0F, 0xFF, 0xE0, 0x00, 0x3F, 0xFF, 0x00, 0x00, 0x1F, 0xFF, 0xF0, 0x00, + 0xFF, 0xF0, 0x3F, 0xFF, 0xC0, 0x00, 0xFF, 0xFC, 0x00, 0x00, 0xFF, 0xFF, + 0xC0, 0x07, 0xFF, 0xC0, 0xFF, 0xFF, 0x00, 0x01, 0xFF, 0xF0, 0x00, 0x03, + 0xF7, 0xFF, 0x80, 0x1F, 0xFF, 0x03, 0xFF, 0xFC, 0x00, 0x07, 0xFF, 0xE0, + 0x00, 0x1F, 0xDF, 0xFE, 0x00, 0xFF, 0xF8, 0x07, 0xFF, 0xF0, 0x00, 0x1F, + 0xFF, 0xC0, 0x00, 0x7F, 0x7F, 0xFC, 0x07, 0xFF, 0xE0, 0x1F, 0xFF, 0xC0, + 0x00, 0x3F, 0xFF, 0x00, 0x03, 0xF8, 0xFF, 0xF8, 0x3F, 0xFF, 0x80, 0x7F, + 0xFF, 0x80, 0x00, 0xFF, 0xFE, 0x00, 0x1F, 0xE3, 0xFF, 0xFB, 0xFF, 0xFC, + 0x01, 0xFF, 0xFE, 0x00, 0x01, 0xFF, 0xFE, 0x01, 0xFF, 0x8F, 0xFF, 0xFF, + 0xFF, 0xF0, 0x03, 0xFF, 0xF8, 0x00, 0x07, 0xFF, 0xFF, 0xFF, 0xFC, 0x1F, + 0xFF, 0xFF, 0xFF, 0x80, 0x0F, 0xFF, 0xE0, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, + 0xF0, 0x7F, 0xFF, 0xFF, 0xFE, 0x00, 0x3F, 0xFF, 0xC0, 0x00, 0x3F, 0xFF, + 0xFF, 0xFF, 0xC0, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0xFF, 0xFF, 0x00, 0x00, + 0x7F, 0xFF, 0xFF, 0xFE, 0x01, 0xFF, 0xFF, 0xFF, 0x80, 0x01, 0xFF, 0xFC, + 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xF8, 0x07, 0xFF, 0xFF, 0xFE, 0x00, 0x07, + 0xFF, 0xF8, 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xC0, 0x0F, 0xFF, 0xFF, 0xF0, + 0x00, 0x1F, 0xFF, 0xE0, 0x00, 0x07, 0xFF, 0xFF, 0xFE, 0x00, 0x1F, 0xFF, + 0xFF, 0x80, 0x00, 0x3F, 0xFF, 0x80, 0x00, 0x0F, 0xFF, 0xFF, 0xF8, 0x00, + 0x3F, 0xFF, 0xFC, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x1F, 0xFF, 0xFF, + 0xC0, 0x00, 0x7F, 0xFF, 0xC0, 0x00, 0x03, 0xFF, 0xFC, 0x00, 0x00, 0x1F, + 0xFF, 0xFE, 0x00, 0x00, 0xFF, 0xFE, 0x00, 0x00, 0x07, 0xFF, 0xF8, 0x00, + 0x00, 0x3F, 0xFF, 0xF0, 0x00, 0x00, 0xFF, 0xE0, 0x00, 0x00, 0x1F, 0xFF, + 0xE0, 0x00, 0x00, 0x3F, 0xFF, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, + 0x7F, 0xFF, 0xC0, 0x00, 0x00, 0x1F, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x03, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xF0, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xE0, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, + 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x07, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xF8, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xF0, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, + 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x07, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xC0, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0x80, 0x00, + 0x00, 0x00, 0x00, 0x03, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xFF, + 0x80, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0xFF, + 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xE0, 0x00, 0x00, 0x00, + 0x01, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x1F, 0xFF, 0xFF, 0x80, 0x00, + 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xE1, 0xFF, 0xFF, 0xFF, 0xFE, + 0x00, 0x00, 0x00, 0x00, 0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, 0x1F, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xFE, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x07, 0xFF, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, + 0xFF, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xF8, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x01, 0xFF, + 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0x80, + 0x00, 0x00, 0x00, 0x00, 0x07, 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00, + 0x00, 0x1F, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, + 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xFC, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x00, + 0x01, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x03, 0xFF, 0xFF, + 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x07, 0xFF, 0xFF, 0xFF, 0xE0, 0x00, + 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00, + 0x3F, 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xFF, + 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFE, 0x00, 0x00, + 0x00, 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x03, + 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x07, 0xFF, 0xFF, 0xFF, + 0xF8, 0x00, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x00, + 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x7F, + 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, + 0x80, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x00, + 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFF, + 0xFF, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xF7, 0xFF, 0xFC, + 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xEF, 0xFF, 0xF8, 0x00, 0x00, 0x00, + 0x00, 0x7F, 0xFF, 0xCF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, + 0x9F, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0x3F, 0xFF, 0xE0, + 0x00, 0x00, 0x00, 0x03, 0xFF, 0xFE, 0x7F, 0xFF, 0xC0, 0x00, 0x00, 0x00, + 0x0F, 0xFF, 0xFC, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xF9, + 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xE3, 0xFF, 0xFE, 0x00, + 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xC3, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x00, + 0xFF, 0xFF, 0x87, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0x0F, + 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x03, 0xFF, 0xFE, 0x1F, 0xFF, 0xF0, 0x00, + 0x00, 0x00, 0x0F, 0xFF, 0xFC, 0x3F, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x1F, + 0xFF, 0xF8, 0x7F, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xE0, 0xFF, + 0xFF, 0x80, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xC0, 0xFF, 0xFF, 0x80, 0x00, + 0x00, 0x00, 0xFF, 0xFF, 0x81, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x01, 0xFF, + 0xFF, 0x03, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x03, 0xFF, 0xFE, 0x07, 0xFF, + 0xFC, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFC, 0x0F, 0xFF, 0xF8, 0x00, 0x00, + 0x00, 0x1F, 0xFF, 0xF8, 0x1F, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x3F, 0xFF, + 0xF0, 0x3F, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xC0, 0x3F, 0xFF, + 0xE0, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x80, 0x7F, 0xFF, 0xC0, 0x00, 0x00, + 0x01, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x07, 0xFF, 0xFE, + 0x01, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFC, 0x03, 0xFF, 0xFE, + 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xF8, 0x07, 0xFF, 0xFE, 0x00, 0x00, 0x00, + 0x3F, 0xFF, 0xF0, 0x0F, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xE0, + 0x0F, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x80, 0x1F, 0xFF, 0xF0, + 0x00, 0x00, 0x01, 0xFF, 0xFF, 0x00, 0x3F, 0xFF, 0xE0, 0x00, 0x00, 0x07, + 0xFF, 0xFE, 0x00, 0x7F, 0xFF, 0xC0, 0x00, 0x00, 0x0F, 0xFF, 0xFC, 0x00, + 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x1F, 0xFF, 0xF8, 0x01, 0xFF, 0xFF, 0x80, + 0x00, 0x00, 0x3F, 0xFF, 0xF0, 0x03, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x7F, + 0xFF, 0xE0, 0x03, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x80, 0x07, + 0xFF, 0xFC, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0x00, 0x0F, 0xFF, 0xF8, 0x00, + 0x00, 0x07, 0xFF, 0xFE, 0x00, 0x1F, 0xFF, 0xF0, 0x00, 0x00, 0x0F, 0xFF, + 0xFC, 0x00, 0x3F, 0xFF, 0xF0, 0x00, 0x00, 0x1F, 0xFF, 0xF8, 0x00, 0x7F, + 0xFF, 0xE0, 0x00, 0x00, 0x3F, 0xFF, 0xF0, 0x00, 0xFF, 0xFF, 0xC0, 0x00, + 0x00, 0x7F, 0xFF, 0xE0, 0x00, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0xFF, 0xFF, + 0xC0, 0x01, 0xFF, 0xFF, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0x00, 0x03, 0xFF, + 0xFE, 0x00, 0x00, 0x07, 0xFF, 0xFE, 0x00, 0x07, 0xFF, 0xFE, 0x00, 0x00, + 0x0F, 0xFF, 0xFC, 0x00, 0x0F, 0xFF, 0xFC, 0x00, 0x00, 0x1F, 0xFF, 0xF8, + 0x00, 0x1F, 0xFF, 0xF8, 0x00, 0x00, 0x3F, 0xFF, 0xF0, 0x00, 0x3F, 0xFF, + 0xF0, 0x00, 0x00, 0x7F, 0xFF, 0xE0, 0x00, 0x3F, 0xFF, 0xE0, 0x00, 0x00, + 0xFF, 0xFF, 0xC0, 0x00, 0x7F, 0xFF, 0xC0, 0x00, 0x03, 0xFF, 0xFF, 0x00, + 0x00, 0xFF, 0xFF, 0xC0, 0x00, 0x07, 0xFF, 0xFE, 0x00, 0x01, 0xFF, 0xFF, + 0x80, 0x00, 0x0F, 0xFF, 0xFC, 0x00, 0x03, 0xFF, 0xFF, 0x00, 0x00, 0x1F, + 0xFF, 0xF8, 0x00, 0x07, 0xFF, 0xFE, 0x00, 0x00, 0x3F, 0xFF, 0xF0, 0x00, + 0x0F, 0xFF, 0xFC, 0x00, 0x00, 0x7F, 0xFF, 0xE0, 0x00, 0x0F, 0xFF, 0xF8, + 0x00, 0x00, 0xFF, 0xFF, 0xC0, 0x00, 0x1F, 0xFF, 0xF0, 0x00, 0x03, 0xFF, + 0xFF, 0x80, 0x00, 0x3F, 0xFF, 0xF0, 0x00, 0x07, 0xFF, 0xFE, 0x00, 0x00, + 0x7F, 0xFF, 0xE0, 0x00, 0x0F, 0xFF, 0xFC, 0x00, 0x00, 0xFF, 0xFF, 0xC0, + 0x00, 0x1F, 0xFF, 0xF8, 0x00, 0x01, 0xFF, 0xFF, 0x80, 0x00, 0x3F, 0xFF, + 0xF0, 0x00, 0x03, 0xFF, 0xFF, 0x00, 0x00, 0x7F, 0xFF, 0xE0, 0x00, 0x03, + 0xFF, 0xFE, 0x00, 0x00, 0xFF, 0xFF, 0xC0, 0x00, 0x07, 0xFF, 0xFE, 0x00, + 0x03, 0xFF, 0xFF, 0x80, 0x00, 0x0F, 0xFF, 0xFC, 0x00, 0x07, 0xFF, 0xFF, + 0x00, 0x00, 0x1F, 0xFF, 0xF8, 0x00, 0x0F, 0xFF, 0xFC, 0x00, 0x00, 0x3F, + 0xFF, 0xF0, 0x00, 0x1F, 0xFF, 0xF8, 0x00, 0x00, 0x7F, 0xFF, 0xE0, 0x00, + 0x3F, 0xFF, 0xF0, 0x00, 0x00, 0xFF, 0xFF, 0xC0, 0x00, 0x7F, 0xFF, 0xE0, + 0x00, 0x00, 0xFF, 0xFF, 0xC0, 0x00, 0xFF, 0xFF, 0xC0, 0x00, 0x01, 0xFF, + 0xFF, 0x80, 0x03, 0xFF, 0xFF, 0x80, 0x00, 0x03, 0xFF, 0xFF, 0x00, 0x07, + 0xFF, 0xFF, 0x00, 0x00, 0x07, 0xFF, 0xFE, 0x00, 0x0F, 0xFF, 0xFC, 0x00, + 0x00, 0x0F, 0xFF, 0xFC, 0x00, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xF8, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x00, 0x7F, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xE0, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xC0, 0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x0F, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFE, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, + 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x01, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xF0, 0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, + 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x1F, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0x80, 0x7F, 0xFF, 0xE0, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0x01, + 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x07, 0xFF, 0xFE, 0x03, 0xFF, 0xFF, 0x80, + 0x00, 0x00, 0x0F, 0xFF, 0xFC, 0x07, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x1F, + 0xFF, 0xF8, 0x0F, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xF8, 0x1F, + 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xF0, 0x3F, 0xFF, 0xF0, 0x00, + 0x00, 0x00, 0xFF, 0xFF, 0xE0, 0x7F, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0xFF, + 0xFF, 0xC1, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0x83, 0xFF, + 0xFF, 0x80, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0x07, 0xFF, 0xFF, 0x00, 0x00, + 0x00, 0x07, 0xFF, 0xFF, 0x0F, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x0F, 0xFF, + 0xFE, 0x1F, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xFC, 0x3F, 0xFF, + 0xF8, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xF8, 0x7F, 0xFF, 0xE0, 0x00, 0x00, + 0x00, 0x3F, 0xFF, 0xF1, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x7F, 0xFF, + 0xE3, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xC7, 0xFF, 0xFF, + 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0xCF, 0xFF, 0xFE, 0x00, 0x00, 0x00, + 0x03, 0xFF, 0xFF, 0x9F, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x07, 0xFF, 0xFF, + 0x3F, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFE, 0xFF, 0xFF, 0xF0, + 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFD, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x00, + 0x1F, 0xFF, 0xFB, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xFF, + 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFE, 0x00, + 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x01, + 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0x80, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xE0, 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x00, 0x07, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFC, 0x00, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x3F, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFC, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x01, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xF8, 0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x0F, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xF0, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0x7F, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0xFF, 0xFF, 0xF0, 0x00, 0x3F, 0xFF, + 0xFF, 0xC1, 0xFF, 0xFF, 0xE0, 0x00, 0x1F, 0xFF, 0xFF, 0x83, 0xFF, 0xFF, + 0xC0, 0x00, 0x1F, 0xFF, 0xFF, 0x07, 0xFF, 0xFF, 0x80, 0x00, 0x1F, 0xFF, + 0xFF, 0x0F, 0xFF, 0xFF, 0x00, 0x00, 0x3F, 0xFF, 0xFE, 0x1F, 0xFF, 0xFE, + 0x00, 0x00, 0x3F, 0xFF, 0xFC, 0x3F, 0xFF, 0xFC, 0x00, 0x00, 0x7F, 0xFF, + 0xF8, 0x7F, 0xFF, 0xF8, 0x00, 0x00, 0xFF, 0xFF, 0xF0, 0xFF, 0xFF, 0xF0, + 0x00, 0x01, 0xFF, 0xFF, 0xE1, 0xFF, 0xFF, 0xE0, 0x00, 0x01, 0xFF, 0xFF, + 0xC3, 0xFF, 0xFF, 0xC0, 0x00, 0x03, 0xFF, 0xFF, 0xC7, 0xFF, 0xFF, 0x80, + 0x00, 0x07, 0xFF, 0xFF, 0x8F, 0xFF, 0xFF, 0x00, 0x00, 0x0F, 0xFF, 0xFF, + 0x1F, 0xFF, 0xFE, 0x00, 0x00, 0x1F, 0xFF, 0xFE, 0x3F, 0xFF, 0xFC, 0x00, + 0x00, 0x3F, 0xFF, 0xFC, 0x7F, 0xFF, 0xF8, 0x00, 0x00, 0x7F, 0xFF, 0xF8, + 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0xFF, 0xFF, 0xF1, 0xFF, 0xFF, 0xE0, 0x00, + 0x01, 0xFF, 0xFF, 0xE3, 0xFF, 0xFF, 0xC0, 0x00, 0x03, 0xFF, 0xFF, 0xC7, + 0xFF, 0xFF, 0x80, 0x00, 0x07, 0xFF, 0xFF, 0x8F, 0xFF, 0xFF, 0x00, 0x00, + 0x0F, 0xFF, 0xFF, 0x1F, 0xFF, 0xFE, 0x00, 0x00, 0x1F, 0xFF, 0xFE, 0x3F, + 0xFF, 0xFC, 0x00, 0x00, 0x3F, 0xFF, 0xFC, 0x7F, 0xFF, 0xF8, 0x00, 0x00, + 0x7F, 0xFF, 0xF8, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0xFF, 0xFF, 0xF1, 0xFF, + 0xFF, 0xE0, 0x00, 0x01, 0xFF, 0xFF, 0xE3, 0xFF, 0xFF, 0xC0, 0x00, 0x03, + 0xFF, 0xFF, 0xC7, 0xFF, 0xFF, 0x80, 0x00, 0x07, 0xFF, 0xFF, 0x8F, 0xFF, + 0xFF, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0x1F, 0xFF, 0xFE, 0x00, 0x00, 0x1F, + 0xFF, 0xFE, 0x3F, 0xFF, 0xFC, 0x00, 0x00, 0x3F, 0xFF, 0xF8, 0x7F, 0xFF, + 0xF8, 0x00, 0x00, 0x7F, 0xFF, 0xF0, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0xFF, + 0xFF, 0xE1, 0xFF, 0xFF, 0xE0, 0x00, 0x01, 0xFF, 0xFF, 0xC3, 0xFF, 0xFF, + 0xC0, 0x00, 0x03, 0xFF, 0xFF, 0x87, 0xFF, 0xFF, 0x80, 0x00, 0x07, 0xFF, + 0xFF, 0x0F, 0xFF, 0xFF, 0x00, 0x00, 0x0F, 0xFF, 0xFE, 0x1F, 0xFF, 0xFE, + 0x00, 0x00, 0x3F, 0xFF, 0xF8, 0x3F, 0xFF, 0xFC, 0x00, 0x00, 0x7F, 0xFF, + 0xF0, 0x7F, 0xFF, 0xF8, 0x00, 0x00, 0xFF, 0xFF, 0xE0, 0xFF, 0xFF, 0xF0, + 0x00, 0x01, 0xFF, 0xFF, 0xC1, 0xFF, 0xFF, 0xE0, 0x00, 0x07, 0xFF, 0xFF, + 0x03, 0xFF, 0xFF, 0xC0, 0x00, 0x0F, 0xFF, 0xFE, 0x07, 0xFF, 0xFF, 0x80, + 0x00, 0x3F, 0xFF, 0xF8, 0x0F, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xF0, + 0x1F, 0xFF, 0xFE, 0x00, 0x07, 0xFF, 0xFF, 0xC0, 0x3F, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0x80, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x00, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xE0, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x07, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xF0, 0x00, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x3F, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFC, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x01, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xF8, 0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x0F, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x1F, 0xFF, 0xFE, 0x00, 0x07, 0xFF, + 0xFF, 0xF0, 0x3F, 0xFF, 0xFC, 0x00, 0x01, 0xFF, 0xFF, 0xF0, 0x7F, 0xFF, + 0xF8, 0x00, 0x01, 0xFF, 0xFF, 0xE0, 0xFF, 0xFF, 0xF0, 0x00, 0x01, 0xFF, + 0xFF, 0xE1, 0xFF, 0xFF, 0xE0, 0x00, 0x01, 0xFF, 0xFF, 0xC3, 0xFF, 0xFF, + 0xC0, 0x00, 0x03, 0xFF, 0xFF, 0xC7, 0xFF, 0xFF, 0x80, 0x00, 0x07, 0xFF, + 0xFF, 0x8F, 0xFF, 0xFF, 0x00, 0x00, 0x07, 0xFF, 0xFF, 0x1F, 0xFF, 0xFE, + 0x00, 0x00, 0x0F, 0xFF, 0xFE, 0x3F, 0xFF, 0xFC, 0x00, 0x00, 0x1F, 0xFF, + 0xFE, 0x7F, 0xFF, 0xF8, 0x00, 0x00, 0x3F, 0xFF, 0xFC, 0xFF, 0xFF, 0xF0, + 0x00, 0x00, 0x3F, 0xFF, 0xF9, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x7F, 0xFF, + 0xF3, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0xFF, 0xFF, 0xE7, 0xFF, 0xFF, 0x80, + 0x00, 0x01, 0xFF, 0xFF, 0xEF, 0xFF, 0xFF, 0x00, 0x00, 0x03, 0xFF, 0xFF, + 0xDF, 0xFF, 0xFE, 0x00, 0x00, 0x07, 0xFF, 0xFF, 0xBF, 0xFF, 0xFC, 0x00, + 0x00, 0x0F, 0xFF, 0xFF, 0x7F, 0xFF, 0xF8, 0x00, 0x00, 0x1F, 0xFF, 0xFE, + 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x3F, 0xFF, 0xFD, 0xFF, 0xFF, 0xE0, 0x00, + 0x00, 0x7F, 0xFF, 0xFB, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0xFF, 0xFF, 0xF7, + 0xFF, 0xFF, 0x80, 0x00, 0x01, 0xFF, 0xFF, 0xEF, 0xFF, 0xFF, 0x00, 0x00, + 0x03, 0xFF, 0xFF, 0xDF, 0xFF, 0xFE, 0x00, 0x00, 0x07, 0xFF, 0xFF, 0xBF, + 0xFF, 0xFC, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0x7F, 0xFF, 0xF8, 0x00, 0x00, + 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, + 0xFF, 0xE0, 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0x00, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x00, 0x00, 0x07, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0x7F, 0xFF, + 0xF8, 0x00, 0x00, 0x1F, 0xFF, 0xFE, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x3F, + 0xFF, 0xFD, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x7F, 0xFF, 0xFB, 0xFF, 0xFF, + 0xC0, 0x00, 0x00, 0xFF, 0xFF, 0xF7, 0xFF, 0xFF, 0x80, 0x00, 0x01, 0xFF, + 0xFF, 0xEF, 0xFF, 0xFF, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xDF, 0xFF, 0xFE, + 0x00, 0x00, 0x07, 0xFF, 0xFF, 0xBF, 0xFF, 0xFC, 0x00, 0x00, 0x0F, 0xFF, + 0xFF, 0x7F, 0xFF, 0xF8, 0x00, 0x00, 0x1F, 0xFF, 0xFE, 0xFF, 0xFF, 0xF0, + 0x00, 0x00, 0x3F, 0xFF, 0xFD, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x7F, 0xFF, + 0xFB, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0xFF, 0xFF, 0xF7, 0xFF, 0xFF, 0x80, + 0x00, 0x03, 0xFF, 0xFF, 0xCF, 0xFF, 0xFF, 0x00, 0x00, 0x07, 0xFF, 0xFF, + 0x9F, 0xFF, 0xFE, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0x3F, 0xFF, 0xFC, 0x00, + 0x00, 0x1F, 0xFF, 0xFE, 0x7F, 0xFF, 0xF8, 0x00, 0x00, 0x3F, 0xFF, 0xFC, + 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0xFF, 0xFF, 0xF1, 0xFF, 0xFF, 0xE0, 0x00, + 0x01, 0xFF, 0xFF, 0xE3, 0xFF, 0xFF, 0xC0, 0x00, 0x07, 0xFF, 0xFF, 0xC7, + 0xFF, 0xFF, 0x80, 0x00, 0x0F, 0xFF, 0xFF, 0x8F, 0xFF, 0xFF, 0x00, 0x00, + 0x3F, 0xFF, 0xFE, 0x1F, 0xFF, 0xFE, 0x00, 0x01, 0xFF, 0xFF, 0xFC, 0x3F, + 0xFF, 0xFC, 0x00, 0x0F, 0xFF, 0xFF, 0xF8, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xE0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC1, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFE, 0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x0F, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xC0, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x7F, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xF0, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x03, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, + 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0x1F, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFC, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x3F, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xC0, + 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x03, 0xFF, + 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, + 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x0F, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFE, 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x00, + 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xE0, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x01, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFE, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x01, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xC0, 0x3F, 0xFF, 0xFF, 0xE0, 0x7F, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, + 0xFE, 0x00, 0x7F, 0xFF, 0xFE, 0x07, 0xFF, 0xFF, 0xE0, 0x00, 0xFF, 0xFF, + 0xF8, 0x1F, 0xFF, 0xFF, 0x00, 0x01, 0xFF, 0xFF, 0xE0, 0x7F, 0xFF, 0xFC, + 0x00, 0x03, 0xFF, 0xFF, 0xC1, 0xFF, 0xFF, 0xE0, 0x00, 0x0F, 0xFF, 0xFF, + 0x0F, 0xFF, 0xFF, 0x80, 0x00, 0x3F, 0xFF, 0xFC, 0x3F, 0xFF, 0xFC, 0x00, + 0x00, 0x7F, 0xFF, 0xF0, 0xFF, 0xFF, 0xF0, 0x00, 0x01, 0xFF, 0xFF, 0xE3, + 0xFF, 0xFF, 0xC0, 0x00, 0x07, 0xFF, 0xFF, 0x9F, 0xFF, 0xFE, 0x00, 0x00, + 0x1F, 0xFF, 0xFE, 0x7F, 0xFF, 0xF8, 0x00, 0x00, 0x3F, 0xFF, 0xF9, 0xFF, + 0xFF, 0xE0, 0x00, 0x00, 0xFF, 0xFF, 0xE7, 0xFF, 0xFF, 0x80, 0x00, 0x03, + 0xFF, 0xFF, 0x9F, 0xFF, 0xFE, 0x00, 0x00, 0x0F, 0xFF, 0xFE, 0x7F, 0xFF, + 0xF8, 0x00, 0x00, 0x3F, 0xFF, 0xF9, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0xFF, + 0xFF, 0xF7, 0xFF, 0xFF, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xDF, 0xFF, 0xFC, + 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x3F, 0xFF, + 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, + 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x00, 0x0F, 0xFF, 0xFF, + 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, + 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFC, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x00, + 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x00, 0x0F, + 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, + 0xC0, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x03, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, + 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, + 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x3F, 0xFF, 0xFF, + 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, + 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, + 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xC0, 0x00, 0x00, + 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, + 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, + 0x00, 0x03, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFF, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xC0, + 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x3F, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xF0, 0x00, + 0x00, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x0F, + 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xFC, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x03, 0xFF, + 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x3F, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, + 0xF0, 0x00, 0x00, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x00, + 0x00, 0x0F, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xFC, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, + 0x03, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xC0, 0x00, + 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, + 0xFF, 0xFC, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x00, + 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x00, 0x0F, + 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, + 0xC0, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x03, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, + 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, + 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x3F, 0xFF, 0xFF, + 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, + 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, + 0xFF, 0xF0, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0x00, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFC, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x3F, + 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x00, 0x0F, 0xFF, + 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, + 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x03, 0xFF, 0xFF, + 0xDF, 0xFF, 0xFC, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0x7F, 0xFF, 0xF8, 0x00, + 0x00, 0x3F, 0xFF, 0xFD, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0xFF, 0xFF, 0xF7, + 0xFF, 0xFF, 0x80, 0x00, 0x03, 0xFF, 0xFF, 0x9F, 0xFF, 0xFE, 0x00, 0x00, + 0x0F, 0xFF, 0xFE, 0x7F, 0xFF, 0xF8, 0x00, 0x00, 0x3F, 0xFF, 0xF9, 0xFF, + 0xFF, 0xE0, 0x00, 0x01, 0xFF, 0xFF, 0xE7, 0xFF, 0xFF, 0x80, 0x00, 0x07, + 0xFF, 0xFF, 0x8F, 0xFF, 0xFE, 0x00, 0x00, 0x1F, 0xFF, 0xFE, 0x3F, 0xFF, + 0xFC, 0x00, 0x00, 0x7F, 0xFF, 0xF8, 0xFF, 0xFF, 0xF0, 0x00, 0x01, 0xFF, + 0xFF, 0xC3, 0xFF, 0xFF, 0xC0, 0x00, 0x0F, 0xFF, 0xFF, 0x07, 0xFF, 0xFF, + 0x80, 0x00, 0x3F, 0xFF, 0xFC, 0x1F, 0xFF, 0xFE, 0x00, 0x00, 0xFF, 0xFF, + 0xF0, 0x7F, 0xFF, 0xFC, 0x00, 0x07, 0xFF, 0xFF, 0xC1, 0xFF, 0xFF, 0xF0, + 0x00, 0x3F, 0xFF, 0xFE, 0x03, 0xFF, 0xFF, 0xE0, 0x00, 0xFF, 0xFF, 0xF8, + 0x0F, 0xFF, 0xFF, 0xC0, 0x0F, 0xFF, 0xFF, 0xE0, 0x1F, 0xFF, 0xFF, 0xE1, + 0xFF, 0xFF, 0xFF, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x01, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0x80, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x1F, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0x80, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x00, 0x01, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0x80, 0x00, 0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x00, 0x0F, 0xFF, + 0xFF, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, + 0x00, 0x00, 0x1F, 0xFF, 0xFF, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x3F, 0xFF, + 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xF8, 0x00, 0x00, + 0x00, 0x00, 0x1F, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xFF, + 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x03, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xC0, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0x80, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x3F, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFC, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x0F, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xC0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x03, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFE, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, + 0x3F, 0xFF, 0xFC, 0x00, 0x7F, 0xFF, 0xFF, 0xF0, 0xFF, 0xFF, 0xF0, 0x00, + 0x3F, 0xFF, 0xFF, 0xC3, 0xFF, 0xFF, 0xC0, 0x00, 0x3F, 0xFF, 0xFF, 0x8F, + 0xFF, 0xFF, 0x00, 0x00, 0x7F, 0xFF, 0xFE, 0x3F, 0xFF, 0xFC, 0x00, 0x00, + 0xFF, 0xFF, 0xF8, 0xFF, 0xFF, 0xF0, 0x00, 0x03, 0xFF, 0xFF, 0xF3, 0xFF, + 0xFF, 0xC0, 0x00, 0x07, 0xFF, 0xFF, 0xCF, 0xFF, 0xFF, 0x00, 0x00, 0x1F, + 0xFF, 0xFF, 0x3F, 0xFF, 0xFC, 0x00, 0x00, 0x3F, 0xFF, 0xFC, 0xFF, 0xFF, + 0xF0, 0x00, 0x00, 0xFF, 0xFF, 0xF3, 0xFF, 0xFF, 0xC0, 0x00, 0x03, 0xFF, + 0xFF, 0xEF, 0xFF, 0xFF, 0x00, 0x00, 0x07, 0xFF, 0xFF, 0xBF, 0xFF, 0xFC, + 0x00, 0x00, 0x1F, 0xFF, 0xFE, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x7F, 0xFF, + 0xFB, 0xFF, 0xFF, 0xC0, 0x00, 0x01, 0xFF, 0xFF, 0xEF, 0xFF, 0xFF, 0x00, + 0x00, 0x07, 0xFF, 0xFF, 0xBF, 0xFF, 0xFC, 0x00, 0x00, 0x1F, 0xFF, 0xFE, + 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x7F, 0xFF, 0xFB, 0xFF, 0xFF, 0xC0, 0x00, + 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFC, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x00, + 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x00, 0x0F, + 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, + 0xC0, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x03, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, + 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, + 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x3F, 0xFF, 0xFF, + 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, + 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, + 0xFF, 0xF0, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0x00, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFC, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x3F, + 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x00, 0x0F, 0xFF, + 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, + 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x03, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFC, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, + 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x00, + 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, + 0xFF, 0xC0, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x03, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, + 0xF0, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, + 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x3F, 0xFF, + 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, + 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x00, 0x0F, 0xFF, 0xFF, + 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, + 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFC, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x00, + 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x00, 0x0F, + 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, + 0xC0, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x03, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, + 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, + 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x3F, 0xFF, 0xFF, + 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, + 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, + 0xFF, 0xF0, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0x00, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFC, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x3F, + 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x00, 0x0F, 0xFF, + 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, + 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x03, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFC, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, + 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x00, + 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x3F, 0xFF, 0xFB, 0xFF, + 0xFF, 0xC0, 0x00, 0x00, 0xFF, 0xFF, 0xEF, 0xFF, 0xFF, 0x00, 0x00, 0x03, + 0xFF, 0xFF, 0xBF, 0xFF, 0xFC, 0x00, 0x00, 0x0F, 0xFF, 0xFE, 0xFF, 0xFF, + 0xF0, 0x00, 0x00, 0x7F, 0xFF, 0xFB, 0xFF, 0xFF, 0xC0, 0x00, 0x01, 0xFF, + 0xFF, 0xEF, 0xFF, 0xFF, 0x00, 0x00, 0x07, 0xFF, 0xFF, 0xBF, 0xFF, 0xFC, + 0x00, 0x00, 0x1F, 0xFF, 0xFE, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x7F, 0xFF, + 0xF3, 0xFF, 0xFF, 0xC0, 0x00, 0x01, 0xFF, 0xFF, 0xCF, 0xFF, 0xFF, 0x00, + 0x00, 0x0F, 0xFF, 0xFF, 0x3F, 0xFF, 0xFC, 0x00, 0x00, 0x3F, 0xFF, 0xFC, + 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0xFF, 0xFF, 0xF3, 0xFF, 0xFF, 0xC0, 0x00, + 0x07, 0xFF, 0xFF, 0x8F, 0xFF, 0xFF, 0x00, 0x00, 0x3F, 0xFF, 0xFE, 0x3F, + 0xFF, 0xFC, 0x00, 0x00, 0xFF, 0xFF, 0xF8, 0xFF, 0xFF, 0xF0, 0x00, 0x07, + 0xFF, 0xFF, 0xC3, 0xFF, 0xFF, 0xC0, 0x00, 0x7F, 0xFF, 0xFF, 0x0F, 0xFF, + 0xFF, 0x00, 0x07, 0xFF, 0xFF, 0xFC, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xE0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x83, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xF0, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFE, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, + 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x3F, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFC, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0x03, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xF0, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, + 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, + 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, + 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, + 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, + 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, + 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, + 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, + 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, + 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, + 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, + 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, + 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, + 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, + 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, + 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, + 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, + 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, + 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, + 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, + 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, + 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, + 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, + 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, + 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0xFF, + 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, + 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, + 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, + 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, + 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, + 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, + 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, + 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, + 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, + 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, + 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, + 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, + 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, + 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, + 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, + 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, + 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, + 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, + 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, + 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, + 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, + 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, + 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, + 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, + 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, + 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, + 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, + 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, + 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, + 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, + 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, + 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, + 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, + 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, + 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, + 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, + 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, + 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, + 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, + 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, + 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, + 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, + 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, + 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, + 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, + 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, + 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, + 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, + 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, + 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, + 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, + 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, + 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, + 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, + 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, + 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, + 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, + 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, + 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, + 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, + 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, + 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, + 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, + 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, + 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, + 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, + 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, + 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, + 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, + 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, + 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, + 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, + 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, + 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, + 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, + 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, + 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, + 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, + 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, + 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, + 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, + 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, + 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x7F, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xFF, + 0xC0, 0x00, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x00, + 0x3F, 0xFF, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, + 0xE0, 0x00, 0x00, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x00, 0x01, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, + 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0x01, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0x80, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, + 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xF8, 0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0x3F, + 0xFF, 0xFF, 0xE0, 0x3F, 0xFF, 0xFF, 0x80, 0xFF, 0xFF, 0xFE, 0x00, 0x3F, + 0xFF, 0xFF, 0x07, 0xFF, 0xFF, 0xE0, 0x00, 0x7F, 0xFF, 0xFC, 0x1F, 0xFF, + 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xF0, 0x7F, 0xFF, 0xFC, 0x00, 0x01, 0xFF, + 0xFF, 0xE3, 0xFF, 0xFF, 0xE0, 0x00, 0x07, 0xFF, 0xFF, 0x8F, 0xFF, 0xFF, + 0x80, 0x00, 0x0F, 0xFF, 0xFE, 0x3F, 0xFF, 0xFC, 0x00, 0x00, 0x3F, 0xFF, + 0xF8, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0xFF, 0xFF, 0xE3, 0xFF, 0xFF, 0xC0, + 0x00, 0x01, 0xFF, 0xFF, 0x9F, 0xFF, 0xFE, 0x00, 0x00, 0x07, 0xFF, 0xFE, + 0x7F, 0xFF, 0xF8, 0x00, 0x00, 0x1F, 0xFF, 0xFD, 0xFF, 0xFF, 0xE0, 0x00, + 0x00, 0x7F, 0xFF, 0xF7, 0xFF, 0xFF, 0x80, 0x00, 0x01, 0xFF, 0xFF, 0xDF, + 0xFF, 0xFE, 0x00, 0x00, 0x07, 0xFF, 0xFF, 0x7F, 0xFF, 0xF8, 0x00, 0x00, + 0x1F, 0xFF, 0xFD, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x7F, 0xFF, 0xF7, 0xFF, + 0xFF, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x00, 0x07, + 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, + 0xC0, 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x01, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x00, 0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, + 0x00, 0x00, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x7F, 0xFF, + 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, + 0x00, 0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x1F, 0xFF, 0xFF, + 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, + 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x00, 0x07, 0xFF, 0xFF, 0xFF, + 0xFF, 0xF0, 0x00, 0x00, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0x00, + 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFC, 0x00, 0x00, 0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x1F, + 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, + 0x00, 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x00, 0x07, 0xFF, + 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xC0, + 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x3F, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xF0, 0x00, + 0x00, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x0F, + 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xFC, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x03, 0xFF, + 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x3F, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, + 0xF0, 0x00, 0x00, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x00, + 0x00, 0x0F, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xFC, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xC0, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, + 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xF0, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x03, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFC, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x3F, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xC0, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x0F, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, + 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x3F, 0xFF, + 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, + 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x0F, 0xFF, 0xFF, + 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, + 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xFF, + 0xFF, 0xF0, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0x00, + 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFC, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x0F, + 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, + 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x00, 0x03, 0xFF, + 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, + 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFC, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, + 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x3F, 0xFF, 0xFF, + 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x00, + 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, + 0xFF, 0xC0, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, + 0xF0, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x3F, + 0xFF, 0xF7, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0xFF, 0xFF, 0xDF, 0xFF, 0xFE, + 0x00, 0x00, 0x03, 0xFF, 0xFF, 0x7F, 0xFF, 0xF8, 0x00, 0x00, 0x0F, 0xFF, + 0xFD, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x3F, 0xFF, 0xF7, 0xFF, 0xFF, 0x80, + 0x00, 0x00, 0xFF, 0xFF, 0xDF, 0xFF, 0xFE, 0x00, 0x00, 0x07, 0xFF, 0xFF, + 0x7F, 0xFF, 0xF8, 0x00, 0x00, 0x1F, 0xFF, 0xFD, 0xFF, 0xFF, 0xE0, 0x00, + 0x00, 0x7F, 0xFF, 0xF7, 0xFF, 0xFF, 0x80, 0x00, 0x01, 0xFF, 0xFF, 0xCF, + 0xFF, 0xFF, 0x00, 0x00, 0x07, 0xFF, 0xFF, 0x3F, 0xFF, 0xFC, 0x00, 0x00, + 0x3F, 0xFF, 0xFC, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0xFF, 0xFF, 0xF3, 0xFF, + 0xFF, 0xC0, 0x00, 0x03, 0xFF, 0xFF, 0xC7, 0xFF, 0xFF, 0x80, 0x00, 0x1F, + 0xFF, 0xFF, 0x1F, 0xFF, 0xFE, 0x00, 0x00, 0x7F, 0xFF, 0xFC, 0x7F, 0xFF, + 0xFC, 0x00, 0x03, 0xFF, 0xFF, 0xF1, 0xFF, 0xFF, 0xF0, 0x00, 0x0F, 0xFF, + 0xFF, 0xC3, 0xFF, 0xFF, 0xE0, 0x00, 0x7F, 0xFF, 0xFF, 0x0F, 0xFF, 0xFF, + 0xE0, 0x07, 0xFF, 0xFF, 0xFC, 0x3F, 0xFF, 0xFF, 0xF9, 0xFF, 0xFF, 0xFF, + 0xF0, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC1, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, + 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xF0, 0x1F, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFB, 0xFF, 0xC0, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xCF, 0xFF, 0x00, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x1F, 0xFC, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, + 0xF8, 0x7F, 0xF0, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xC1, 0xFF, 0xC0, 0x07, + 0xFF, 0xFF, 0xFF, 0xFF, 0x07, 0xFF, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xF8, + 0x0F, 0xFC, 0x00, 0x1F, 0xFF, 0xFF, 0xFF, 0x80, 0x3F, 0xF0, 0x00, 0x1F, + 0xFF, 0xFF, 0xFC, 0x00, 0xFF, 0xC0, 0x00, 0x3F, 0xFF, 0xFF, 0xE0, 0x03, + 0xFF, 0x00, 0x00, 0x3F, 0xFF, 0xFE, 0x00, 0x0F, 0xFC, 0x00, 0x00, 0x1F, + 0xFF, 0xC0, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x1F, 0xFF, + 0xFF, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, + 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x00, + 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x00, 0x07, 0xFF, 0xFF, + 0xFF, 0xFF, 0xF8, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, + 0x00, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x3F, 0xFF, 0xFF, + 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x00, + 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFE, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x00, + 0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, + 0xFF, 0xF0, 0x00, 0x00, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0x00, 0x00, + 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, + 0xFF, 0x80, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x01, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFC, 0x00, 0x00, 0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x00, 0x00, 0x0F, + 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, + 0xE0, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x7F, + 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0x00, 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x00, 0x00, 0x03, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x00, 0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, + 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x1F, 0xFF, + 0xFF, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, + 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x00, + 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x00, 0x07, 0xFF, 0xFF, + 0xFF, 0xFF, 0xF8, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, + 0x00, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x3F, 0xFF, 0xFF, + 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x00, + 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFE, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x00, + 0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, + 0xFF, 0xF0, 0x00, 0x00, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0x00, 0x00, + 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, + 0xFF, 0x80, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x01, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFC, 0x00, 0x00, 0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x00, 0x00, 0x0F, + 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, + 0xE0, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x7F, + 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0x00, 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x00, 0x00, 0x03, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x00, 0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xF0, 0x00, 0x00, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0x00, 0x00, + 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, + 0xFF, 0x80, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x01, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFC, 0x00, 0x00, 0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x00, 0x00, 0x0F, + 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, + 0xE0, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x7F, + 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0x00, 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x00, 0x00, 0x03, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x00, 0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, + 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x1F, 0xFF, + 0xFF, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, + 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x00, + 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x00, 0x07, 0xFF, 0xFF, + 0xFF, 0xFF, 0xF8, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, + 0x00, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x3F, 0xFF, 0xFF, + 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x00, + 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFE, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x00, + 0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, + 0xFF, 0xF0, 0x00, 0x00, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0x00, 0x00, + 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, + 0xFF, 0x80, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x01, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFC, 0x00, 0x00, 0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x00, 0x00, 0x0F, + 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, + 0xE0, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x7F, + 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0x00, 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x00, 0x00, 0x03, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x00, 0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, + 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x1F, 0xFF, + 0xFF, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, + 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x00, + 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x00, 0x07, 0xFF, 0xFF, + 0xFF, 0xFF, 0xF8, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, + 0x00, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x3F, 0xFF, 0xFF, + 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x00, + 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFE, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x00, + 0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, + 0xFF, 0xF0, 0x00, 0x00, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0x00, 0x00, + 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, + 0xFF, 0x80, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x01, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFC, 0x00, 0x00, 0x07, 0xFF, 0xFF, 0x80, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xF0, 0x00, 0x00, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x00, + 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xFC, 0x00, + 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x03, 0xFF, + 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, + 0x00, 0x3F, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0x00, + 0x00, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00, 0xFF, + 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xFC, 0x00, 0x00, 0x00, + 0x00, 0x0F, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xC0, + 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x3F, + 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0x00, 0x00, 0x00, + 0x00, 0x03, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xF0, + 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x0F, + 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xC0, 0x00, 0x00, + 0x00, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xFC, + 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x03, + 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, + 0x00, 0x00, 0x3F, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFF, + 0x00, 0x00, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00, + 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xFC, 0x00, 0x00, + 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x03, 0xFF, 0xFF, + 0xC0, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, + 0x3F, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0x00, 0x00, + 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, + 0xF0, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x00, + 0x0F, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xC0, 0x00, + 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, + 0xFC, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, + 0x03, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xF0, 0x00, + 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFF, + 0xFF, 0x00, 0x00, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x00, + 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xFC, 0x00, + 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x03, 0xFF, + 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, + 0x00, 0x3F, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0x00, + 0x00, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00, 0xFF, + 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xFC, 0x00, 0x00, 0x00, + 0x00, 0x0F, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xC0, + 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x3F, + 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0x00, 0x00, 0x00, + 0x00, 0x03, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xF0, + 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x0F, + 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xC0, 0x00, 0x00, + 0x00, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xFC, + 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x03, + 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, + 0x00, 0x00, 0x3F, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFF, + 0x00, 0x00, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00, + 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xFC, 0x00, 0x00, + 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x03, 0xFF, 0xFF, + 0xC0, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, + 0x3F, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0x00, 0x00, + 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, + 0xF0, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x00, + 0x0F, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xC0, 0x00, + 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, + 0xFC, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, + 0x03, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xF0, 0x00, + 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0x0F, 0xFF, + 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, + 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, + 0xFF, 0xC0, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x03, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, + 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, + 0xFF, 0xF0, 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x00, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, + 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x03, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFC, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x3F, + 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, + 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x00, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0x0F, + 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, + 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x3F, 0xFF, 0xFF, + 0xFF, 0xFF, 0xC0, 0x00, 0x0F, 0xFF, 0xFF, 0x7F, 0xFF, 0xF0, 0x00, 0x03, + 0xFF, 0xFF, 0xDF, 0xFF, 0xFC, 0x00, 0x00, 0xFF, 0xFF, 0xF7, 0xFF, 0xFF, + 0x00, 0x00, 0x3F, 0xFF, 0xFD, 0xFF, 0xFF, 0xC0, 0x00, 0x0F, 0xFF, 0xFF, + 0x7F, 0xFF, 0xF0, 0x00, 0x03, 0xFF, 0xFF, 0xDF, 0xFF, 0xFC, 0x00, 0x00, + 0xFF, 0xFF, 0xF7, 0xFF, 0xFF, 0x80, 0x00, 0x3F, 0xFF, 0xFD, 0xFF, 0xFF, + 0xE0, 0x00, 0x0F, 0xFF, 0xFE, 0x7F, 0xFF, 0xF8, 0x00, 0x07, 0xFF, 0xFF, + 0x8F, 0xFF, 0xFE, 0x00, 0x01, 0xFF, 0xFF, 0xE3, 0xFF, 0xFF, 0xC0, 0x00, + 0x7F, 0xFF, 0xF8, 0xFF, 0xFF, 0xF0, 0x00, 0x3F, 0xFF, 0xFC, 0x3F, 0xFF, + 0xFE, 0x00, 0x0F, 0xFF, 0xFF, 0x0F, 0xFF, 0xFF, 0x80, 0x07, 0xFF, 0xFF, + 0xC1, 0xFF, 0xFF, 0xF0, 0x03, 0xFF, 0xFF, 0xF0, 0x7F, 0xFF, 0xFF, 0x87, + 0xFF, 0xFF, 0xF8, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x03, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xC0, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0x07, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xF8, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x1F, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x00, 0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0x80, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0x1F, 0xFF, 0xFF, + 0xFF, 0xFF, 0xE0, 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x00, + 0x7F, 0xFF, 0xFF, 0xFF, 0xF8, 0x00, 0x00, 0x07, 0xFF, 0xFF, 0xFF, 0xF8, + 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x07, 0xFF, + 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xF8, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x7F, 0xC0, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, + 0x07, 0xFF, 0xFF, 0xCF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xF8, + 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0x8F, 0xFF, 0xFF, 0x00, + 0x00, 0x00, 0xFF, 0xFF, 0xF0, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x0F, 0xFF, + 0xFF, 0x0F, 0xFF, 0xFF, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0xE0, 0xFF, 0xFF, + 0xF0, 0x00, 0x00, 0x1F, 0xFF, 0xFE, 0x0F, 0xFF, 0xFF, 0x00, 0x00, 0x03, + 0xFF, 0xFF, 0xE0, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x3F, 0xFF, 0xFC, 0x0F, + 0xFF, 0xFF, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xC0, 0xFF, 0xFF, 0xF0, 0x00, + 0x00, 0x7F, 0xFF, 0xFC, 0x0F, 0xFF, 0xFF, 0x00, 0x00, 0x07, 0xFF, 0xFF, + 0x80, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x7F, 0xFF, 0xF8, 0x0F, 0xFF, 0xFF, + 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0x80, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0xFF, + 0xFF, 0xF0, 0x0F, 0xFF, 0xFF, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0x00, 0xFF, + 0xFF, 0xF0, 0x00, 0x01, 0xFF, 0xFF, 0xF0, 0x0F, 0xFF, 0xFF, 0x00, 0x00, + 0x1F, 0xFF, 0xFE, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x01, 0xFF, 0xFF, 0xE0, + 0x0F, 0xFF, 0xFF, 0x00, 0x00, 0x3F, 0xFF, 0xFC, 0x00, 0xFF, 0xFF, 0xF0, + 0x00, 0x03, 0xFF, 0xFF, 0xC0, 0x0F, 0xFF, 0xFF, 0x00, 0x00, 0x7F, 0xFF, + 0xFC, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x07, 0xFF, 0xFF, 0x80, 0x0F, 0xFF, + 0xFF, 0x00, 0x00, 0x7F, 0xFF, 0xF8, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x0F, + 0xFF, 0xFF, 0x80, 0x0F, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xF0, 0x00, + 0xFF, 0xFF, 0xF0, 0x00, 0x0F, 0xFF, 0xFF, 0x00, 0x0F, 0xFF, 0xFF, 0x00, + 0x01, 0xFF, 0xFF, 0xF0, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x1F, 0xFF, 0xFE, + 0x00, 0x0F, 0xFF, 0xFF, 0x00, 0x01, 0xFF, 0xFF, 0xE0, 0x00, 0xFF, 0xFF, + 0xF0, 0x00, 0x3F, 0xFF, 0xFC, 0x00, 0x0F, 0xFF, 0xFF, 0x00, 0x03, 0xFF, + 0xFF, 0xC0, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x3F, 0xFF, 0xFC, 0x00, 0x0F, + 0xFF, 0xFF, 0x00, 0x07, 0xFF, 0xFF, 0x80, 0x00, 0xFF, 0xFF, 0xF0, 0x00, + 0x7F, 0xFF, 0xF8, 0x00, 0x0F, 0xFF, 0xFF, 0x00, 0x0F, 0xFF, 0xFF, 0x80, + 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x0F, 0xFF, 0xFF, + 0x00, 0x0F, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xF0, 0x01, 0xFF, 0xFF, + 0xF0, 0x00, 0x0F, 0xFF, 0xFF, 0x00, 0x1F, 0xFF, 0xFE, 0x00, 0x00, 0xFF, + 0xFF, 0xF0, 0x01, 0xFF, 0xFF, 0xE0, 0x00, 0x0F, 0xFF, 0xFF, 0x00, 0x3F, + 0xFF, 0xFE, 0x00, 0x00, 0xFF, 0xFF, 0xF0, 0x03, 0xFF, 0xFF, 0xC0, 0x00, + 0x0F, 0xFF, 0xFF, 0x00, 0x3F, 0xFF, 0xFC, 0x00, 0x00, 0xFF, 0xFF, 0xF0, + 0x07, 0xFF, 0xFF, 0x80, 0x00, 0x0F, 0xFF, 0xFF, 0x00, 0x7F, 0xFF, 0xF8, + 0x00, 0x00, 0xFF, 0xFF, 0xF0, 0x07, 0xFF, 0xFF, 0x80, 0x00, 0x0F, 0xFF, + 0xFF, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0xFF, 0xFF, 0xF0, 0x0F, 0xFF, + 0xFF, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0x01, 0xFF, 0xFF, 0xF0, 0x00, 0x00, + 0xFF, 0xFF, 0xF0, 0x1F, 0xFF, 0xFE, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0x01, + 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0xFF, 0xFF, 0xF0, 0x3F, 0xFF, 0xFE, 0x00, + 0x00, 0x0F, 0xFF, 0xFF, 0x03, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0xFF, 0xFF, + 0xF0, 0x3F, 0xFF, 0xFC, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0x07, 0xFF, 0xFF, + 0x80, 0x00, 0x00, 0xFF, 0xFF, 0xF0, 0x7F, 0xFF, 0xF8, 0x00, 0x00, 0x0F, + 0xFF, 0xFF, 0x07, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0xFF, 0xFF, 0xF0, 0xFF, + 0xFF, 0xF0, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0x0F, 0xFF, 0xFF, 0x00, 0x00, + 0x00, 0xFF, 0xFF, 0xF0, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x0F, 0xFF, 0xFF, + 0x1F, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xF1, 0xFF, 0xFF, 0xE0, + 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0x3F, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0xFF, + 0xFF, 0xF3, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0x3F, 0xFF, + 0xFC, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xF7, 0xFF, 0xFF, 0xC0, 0x00, 0x00, + 0x0F, 0xFF, 0xFF, 0x7F, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xF7, + 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, + 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x0F, 0xFF, + 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, + 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x00, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, + 0xFF, 0xE0, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, + 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, + 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xF7, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x0F, + 0xFF, 0xFF, 0x7F, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xF7, 0xFF, + 0xFF, 0xC0, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0x3F, 0xFF, 0xFC, 0x00, 0x00, + 0x00, 0xFF, 0xFF, 0xF3, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x0F, 0xFF, 0xFF, + 0x3F, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xF1, 0xFF, 0xFF, 0xE0, + 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0x1F, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFF, + 0xFF, 0xF0, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0x0F, 0xFF, + 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xF0, 0xFF, 0xFF, 0xF8, 0x00, 0x00, + 0x0F, 0xFF, 0xFF, 0x07, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0xFF, 0xFF, 0xF0, + 0x7F, 0xFF, 0xFC, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0x07, 0xFF, 0xFF, 0xC0, + 0x00, 0x00, 0xFF, 0xFF, 0xF0, 0x3F, 0xFF, 0xFC, 0x00, 0x00, 0x0F, 0xFF, + 0xFF, 0x03, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0xFF, 0xFF, 0xF0, 0x3F, 0xFF, + 0xFE, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0x01, 0xFF, 0xFF, 0xE0, 0x00, 0x00, + 0xFF, 0xFF, 0xF0, 0x1F, 0xFF, 0xFF, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0x00, + 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0xFF, 0xFF, 0xF0, 0x0F, 0xFF, 0xFF, 0x80, + 0x00, 0x0F, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xF8, 0x00, 0x00, 0xFF, 0xFF, + 0xF0, 0x07, 0xFF, 0xFF, 0x80, 0x00, 0x0F, 0xFF, 0xFF, 0x00, 0x7F, 0xFF, + 0xFC, 0x00, 0x00, 0xFF, 0xFF, 0xF0, 0x07, 0xFF, 0xFF, 0xC0, 0x00, 0x0F, + 0xFF, 0xFF, 0x00, 0x3F, 0xFF, 0xFC, 0x00, 0x00, 0xFF, 0xFF, 0xF0, 0x03, + 0xFF, 0xFF, 0xE0, 0x00, 0x0F, 0xFF, 0xFF, 0x00, 0x1F, 0xFF, 0xFE, 0x00, + 0x00, 0xFF, 0xFF, 0xF0, 0x01, 0xFF, 0xFF, 0xF0, 0x00, 0x0F, 0xFF, 0xFF, + 0x00, 0x1F, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0xFF, 0xFF, + 0xF0, 0x00, 0x0F, 0xFF, 0xFF, 0x00, 0x0F, 0xFF, 0xFF, 0x80, 0x00, 0xFF, + 0xFF, 0xF0, 0x00, 0xFF, 0xFF, 0xF8, 0x00, 0x0F, 0xFF, 0xFF, 0x00, 0x07, + 0xFF, 0xFF, 0x80, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x7F, 0xFF, 0xFC, 0x00, + 0x0F, 0xFF, 0xFF, 0x00, 0x03, 0xFF, 0xFF, 0xC0, 0x00, 0xFF, 0xFF, 0xF0, + 0x00, 0x3F, 0xFF, 0xFE, 0x00, 0x0F, 0xFF, 0xFF, 0x00, 0x03, 0xFF, 0xFF, + 0xE0, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x1F, 0xFF, 0xFE, 0x00, 0x0F, 0xFF, + 0xFF, 0x00, 0x01, 0xFF, 0xFF, 0xF0, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x1F, + 0xFF, 0xFF, 0x00, 0x0F, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xF0, 0x00, + 0xFF, 0xFF, 0xF0, 0x00, 0x0F, 0xFF, 0xFF, 0x80, 0x0F, 0xFF, 0xFF, 0x00, + 0x00, 0xFF, 0xFF, 0xF8, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x07, 0xFF, 0xFF, + 0xC0, 0x0F, 0xFF, 0xFF, 0x00, 0x00, 0x7F, 0xFF, 0xFC, 0x00, 0xFF, 0xFF, + 0xF0, 0x00, 0x03, 0xFF, 0xFF, 0xC0, 0x0F, 0xFF, 0xFF, 0x00, 0x00, 0x3F, + 0xFF, 0xFE, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x03, 0xFF, 0xFF, 0xE0, 0x0F, + 0xFF, 0xFF, 0x00, 0x00, 0x1F, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xF0, 0x00, + 0x01, 0xFF, 0xFF, 0xF0, 0x0F, 0xFF, 0xFF, 0x00, 0x00, 0x1F, 0xFF, 0xFF, + 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0xFF, 0xFF, 0xF8, 0x0F, 0xFF, 0xFF, + 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0x80, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x7F, + 0xFF, 0xF8, 0x0F, 0xFF, 0xFF, 0x00, 0x00, 0x07, 0xFF, 0xFF, 0xC0, 0xFF, + 0xFF, 0xF0, 0x00, 0x00, 0x7F, 0xFF, 0xFC, 0x0F, 0xFF, 0xFF, 0x00, 0x00, + 0x03, 0xFF, 0xFF, 0xE0, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x3F, 0xFF, 0xFE, + 0x0F, 0xFF, 0xFF, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xE0, 0xFF, 0xFF, 0xF0, + 0x00, 0x00, 0x1F, 0xFF, 0xFF, 0x0F, 0xFF, 0xFF, 0x00, 0x00, 0x01, 0xFF, + 0xFF, 0xF0, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0x0F, 0xFF, + 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xF8, 0xFF, 0xFF, 0xF0, 0x00, 0x00, + 0x0F, 0xFF, 0xFF, 0x8F, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xFC, + 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x07, 0xFF, 0xFF, 0xCF, 0xFF, 0xFF, 0x00, + 0x00, 0x00, 0x7F, 0xFF, 0xFC, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x03, 0xFF, + 0xFF, 0xEF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xFE, 0xFF, 0xFF, + 0xF0, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xF0, 0xFF, 0xFF, 0xF0, 0x00, 0x00, + 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, + 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, + 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, + 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, + 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, + 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, + 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, + 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, + 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, + 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, + 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, + 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, + 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, + 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, + 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, + 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, + 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, + 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, + 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, + 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, + 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, + 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, + 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, + 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, + 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, + 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, + 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, + 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, + 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, + 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, + 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, + 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, + 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, + 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, + 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, + 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, + 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, + 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, + 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, + 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, + 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, + 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, + 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, + 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, + 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, + 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, + 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, + 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, + 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, + 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, + 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, + 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, + 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, + 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, + 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, + 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, + 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, + 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, + 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, + 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, + 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, + 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, + 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, + 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, + 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, + 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, + 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xF8, 0x00, 0x00, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xC0, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, + 0x00, 0x00, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, + 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, + 0x00, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, + 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x00, 0x00, + 0x00, 0x00, 0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0x00, 0x00, + 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x00, 0x00, 0x00, + 0x00, 0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x00, + 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x00, + 0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x0F, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFC, 0x00, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xC0, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, + 0x00, 0x00, 0x00, 0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, + 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x00, + 0x00, 0x00, 0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0x00, + 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x00, 0x00, + 0x00, 0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x00, + 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, + 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, + 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0xFF, 0x00, 0x00, 0x00, 0x0F, + 0xFF, 0xEF, 0xFF, 0xFF, 0xFF, 0xF7, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, + 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0xFF, 0x80, 0x00, 0x00, 0x0F, 0xFF, + 0xEF, 0xFF, 0xFF, 0xFF, 0xF7, 0xFF, 0xF8, 0x00, 0x00, 0x01, 0xFF, 0xFE, + 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0xFF, 0x80, 0x00, 0x00, 0x1F, 0xFF, 0xCF, + 0xFF, 0xFF, 0xFF, 0xF3, 0xFF, 0xF8, 0x00, 0x00, 0x01, 0xFF, 0xFD, 0xFF, + 0xFF, 0xFF, 0xFF, 0x3F, 0xFF, 0x80, 0x00, 0x00, 0x1F, 0xFF, 0xDF, 0xFF, + 0xFF, 0xFF, 0xF3, 0xFF, 0xFC, 0x00, 0x00, 0x01, 0xFF, 0xFD, 0xFF, 0xFF, + 0xFF, 0xFF, 0x3F, 0xFF, 0xC0, 0x00, 0x00, 0x1F, 0xFF, 0xDF, 0xFF, 0xFF, + 0xFF, 0xF1, 0xFF, 0xFC, 0x00, 0x00, 0x03, 0xFF, 0xF9, 0xFF, 0xFF, 0xFF, + 0xFF, 0x1F, 0xFF, 0xC0, 0x00, 0x00, 0x3F, 0xFF, 0x9F, 0xFF, 0xFF, 0xFF, + 0xF1, 0xFF, 0xFC, 0x00, 0x00, 0x03, 0xFF, 0xF9, 0xFF, 0xFF, 0xFF, 0xFF, + 0x1F, 0xFF, 0xE0, 0x00, 0x00, 0x3F, 0xFF, 0x9F, 0xFF, 0xFF, 0xFF, 0xF1, + 0xFF, 0xFE, 0x00, 0x00, 0x03, 0xFF, 0xF9, 0xFF, 0xFF, 0xFF, 0xFF, 0x0F, + 0xFF, 0xE0, 0x00, 0x00, 0x7F, 0xFF, 0x1F, 0xFF, 0xFF, 0xFF, 0xF0, 0xFF, + 0xFE, 0x00, 0x00, 0x07, 0xFF, 0xF1, 0xFF, 0xFF, 0xFF, 0xFF, 0x0F, 0xFF, + 0xE0, 0x00, 0x00, 0x7F, 0xFF, 0x1F, 0xFF, 0xFF, 0xFF, 0xF8, 0xFF, 0xFE, + 0x00, 0x00, 0x07, 0xFF, 0xF1, 0xFF, 0xFF, 0xFF, 0xFF, 0x8F, 0xFF, 0xF0, + 0x00, 0x00, 0x7F, 0xFF, 0x1F, 0xFF, 0xFF, 0xFF, 0xF8, 0x7F, 0xFF, 0x00, + 0x00, 0x0F, 0xFF, 0xE1, 0xFF, 0xFF, 0xFF, 0xFF, 0x87, 0xFF, 0xF0, 0x00, + 0x00, 0xFF, 0xFE, 0x1F, 0xFF, 0xFF, 0xFF, 0xF8, 0x7F, 0xFF, 0x00, 0x00, + 0x0F, 0xFF, 0xE1, 0xFF, 0xFF, 0xFF, 0xFF, 0x87, 0xFF, 0xF0, 0x00, 0x00, + 0xFF, 0xFE, 0x1F, 0xFF, 0xFF, 0xFF, 0xF8, 0x7F, 0xFF, 0x80, 0x00, 0x0F, + 0xFF, 0xE1, 0xFF, 0xFF, 0xFF, 0xFF, 0x83, 0xFF, 0xF8, 0x00, 0x00, 0xFF, + 0xFC, 0x1F, 0xFF, 0xFF, 0xFF, 0xF8, 0x3F, 0xFF, 0x80, 0x00, 0x1F, 0xFF, + 0xC1, 0xFF, 0xFF, 0xFF, 0xFF, 0x83, 0xFF, 0xF8, 0x00, 0x01, 0xFF, 0xFC, + 0x1F, 0xFF, 0xFF, 0xFF, 0xF8, 0x3F, 0xFF, 0x80, 0x00, 0x1F, 0xFF, 0xC1, + 0xFF, 0xFF, 0xFF, 0xFF, 0x83, 0xFF, 0xFC, 0x00, 0x01, 0xFF, 0xFC, 0x1F, + 0xFF, 0xFF, 0xFF, 0xF8, 0x1F, 0xFF, 0xC0, 0x00, 0x1F, 0xFF, 0x81, 0xFF, + 0xFF, 0xFF, 0xFF, 0x81, 0xFF, 0xFC, 0x00, 0x03, 0xFF, 0xF8, 0x1F, 0xFF, + 0xFF, 0xFF, 0xF8, 0x1F, 0xFF, 0xC0, 0x00, 0x3F, 0xFF, 0x81, 0xFF, 0xFF, + 0xFF, 0xFF, 0x81, 0xFF, 0xFC, 0x00, 0x03, 0xFF, 0xF8, 0x1F, 0xFF, 0xFF, + 0xFF, 0xF8, 0x1F, 0xFF, 0xE0, 0x00, 0x3F, 0xFF, 0x81, 0xFF, 0xFF, 0xFF, + 0xFF, 0x80, 0xFF, 0xFE, 0x00, 0x03, 0xFF, 0xF0, 0x1F, 0xFF, 0xFF, 0xFF, + 0xF8, 0x0F, 0xFF, 0xE0, 0x00, 0x3F, 0xFF, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, + 0x80, 0xFF, 0xFE, 0x00, 0x07, 0xFF, 0xF0, 0x1F, 0xFF, 0xFF, 0xFF, 0xF8, + 0x0F, 0xFF, 0xE0, 0x00, 0x7F, 0xFF, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, + 0xFF, 0xFF, 0x00, 0x07, 0xFF, 0xF0, 0x1F, 0xFF, 0xFF, 0xFF, 0xF8, 0x07, + 0xFF, 0xF0, 0x00, 0x7F, 0xFE, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x7F, + 0xFF, 0x00, 0x07, 0xFF, 0xE0, 0x1F, 0xFF, 0xFF, 0xFF, 0xF8, 0x07, 0xFF, + 0xF0, 0x00, 0xFF, 0xFE, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x7F, 0xFF, + 0x00, 0x0F, 0xFF, 0xE0, 0x1F, 0xFF, 0xFF, 0xFF, 0xF8, 0x07, 0xFF, 0xF0, + 0x00, 0xFF, 0xFE, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x3F, 0xFF, 0x80, + 0x0F, 0xFF, 0xC0, 0x1F, 0xFF, 0xFF, 0xFF, 0xF8, 0x03, 0xFF, 0xF8, 0x00, + 0xFF, 0xFC, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x3F, 0xFF, 0x80, 0x0F, + 0xFF, 0xC0, 0x1F, 0xFF, 0xFF, 0xFF, 0xF8, 0x03, 0xFF, 0xF8, 0x01, 0xFF, + 0xFC, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x3F, 0xFF, 0x80, 0x1F, 0xFF, + 0xC0, 0x1F, 0xFF, 0xFF, 0xFF, 0xF8, 0x01, 0xFF, 0xFC, 0x01, 0xFF, 0xF8, + 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x1F, 0xFF, 0xC0, 0x1F, 0xFF, 0x80, + 0x1F, 0xFF, 0xFF, 0xFF, 0xF8, 0x01, 0xFF, 0xFC, 0x01, 0xFF, 0xF8, 0x03, + 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x1F, 0xFF, 0xC0, 0x3F, 0xFF, 0x80, 0x3F, + 0xFF, 0xFF, 0xFF, 0xF8, 0x01, 0xFF, 0xFC, 0x03, 0xFF, 0xF8, 0x03, 0xFF, + 0xFF, 0xFF, 0xFF, 0x80, 0x0F, 0xFF, 0xE0, 0x3F, 0xFF, 0x80, 0x3F, 0xFF, + 0xFF, 0xFF, 0xF8, 0x00, 0xFF, 0xFE, 0x03, 0xFF, 0xF0, 0x03, 0xFF, 0xFF, + 0xFF, 0xFF, 0x80, 0x0F, 0xFF, 0xE0, 0x3F, 0xFF, 0x00, 0x3F, 0xFF, 0xFF, + 0xFF, 0xF8, 0x00, 0xFF, 0xFE, 0x03, 0xFF, 0xF0, 0x03, 0xFF, 0xFF, 0xFF, + 0xFF, 0x80, 0x07, 0xFF, 0xE0, 0x7F, 0xFF, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, + 0xF8, 0x00, 0x7F, 0xFF, 0x07, 0xFF, 0xF0, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, + 0x80, 0x07, 0xFF, 0xF0, 0x7F, 0xFE, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xF8, + 0x00, 0x7F, 0xFF, 0x07, 0xFF, 0xE0, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, + 0x07, 0xFF, 0xF0, 0x7F, 0xFE, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xF8, 0x00, + 0x3F, 0xFF, 0x0F, 0xFF, 0xE0, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x03, + 0xFF, 0xF8, 0xFF, 0xFE, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xF8, 0x00, 0x3F, + 0xFF, 0x8F, 0xFF, 0xC0, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x03, 0xFF, + 0xF8, 0xFF, 0xFC, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xF8, 0x00, 0x3F, 0xFF, + 0x8F, 0xFF, 0xC0, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x01, 0xFF, 0xF9, + 0xFF, 0xFC, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xF8, 0x00, 0x1F, 0xFF, 0xDF, + 0xFF, 0xC0, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x01, 0xFF, 0xFD, 0xFF, + 0xF8, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xF8, 0x00, 0x1F, 0xFF, 0xDF, 0xFF, + 0x80, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x01, 0xFF, 0xFD, 0xFF, 0xF8, + 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xF8, 0x00, 0x0F, 0xFF, 0xDF, 0xFF, 0x80, + 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0xFF, 0xFF, 0xFF, 0xF8, 0x00, + 0x3F, 0xFF, 0xFF, 0xFF, 0xF8, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0x00, 0x03, + 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x3F, + 0xFF, 0xFF, 0xFF, 0xF8, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0x00, 0x03, 0xFF, + 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x7F, 0xFF, 0xFF, 0xF0, 0x00, 0x3F, 0xFF, + 0xFF, 0xFF, 0xF8, 0x00, 0x07, 0xFF, 0xFF, 0xFF, 0x00, 0x03, 0xFF, 0xFF, + 0xFF, 0xFF, 0x80, 0x00, 0x7F, 0xFF, 0xFF, 0xE0, 0x00, 0x3F, 0xFF, 0xFF, + 0xFF, 0xF8, 0x00, 0x07, 0xFF, 0xFF, 0xFE, 0x00, 0x03, 0xFF, 0xFF, 0xFF, + 0xFF, 0x80, 0x00, 0x7F, 0xFF, 0xFF, 0xE0, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, + 0xF8, 0x00, 0x03, 0xFF, 0xFF, 0xFE, 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, + 0x80, 0x00, 0x3F, 0xFF, 0xFF, 0xE0, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xF8, + 0x00, 0x03, 0xFF, 0xFF, 0xFC, 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, + 0x00, 0x3F, 0xFF, 0xFF, 0xC0, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xF8, 0x00, + 0x03, 0xFF, 0xFF, 0xFC, 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x00, + 0x1F, 0xFF, 0xFF, 0xC0, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xF8, 0x00, 0x01, + 0xFF, 0xFF, 0xFC, 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x1F, + 0xFF, 0xFF, 0x80, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xF8, 0x00, 0x01, 0xFF, + 0xFF, 0xF8, 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x1F, 0xFF, + 0xFF, 0x80, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xF8, 0x00, 0x00, 0xFF, 0xFF, + 0xF8, 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x0F, 0xFF, 0xFF, + 0x80, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xF8, 0x00, 0x00, 0xFF, 0xFF, 0xF0, + 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x0F, 0xFF, 0xFF, 0x00, + 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xF8, 0x00, 0x00, 0xFF, 0xFF, 0xF0, 0x00, + 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x07, 0xFF, 0xFF, 0x00, 0x00, + 0x3F, 0xFF, 0xFF, 0xFF, 0xF8, 0x00, 0x00, 0x7F, 0xFF, 0xF0, 0x00, 0x03, + 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x07, 0xFF, 0xFE, 0x00, 0x00, 0x3F, + 0xFF, 0xFF, 0xFF, 0xF8, 0x00, 0x00, 0x7F, 0xFF, 0xE0, 0x00, 0x03, 0xFF, + 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x03, 0xFF, 0xFE, 0x00, 0x00, 0x3F, 0xFF, + 0xFF, 0xFF, 0xF8, 0x00, 0x00, 0x3F, 0xFF, 0xE0, 0x00, 0x03, 0xFF, 0xFF, + 0xFF, 0xFF, 0x80, 0x00, 0x03, 0xFF, 0xFE, 0x00, 0x00, 0x3F, 0xFF, 0xFF, + 0xFF, 0xF8, 0x00, 0x00, 0x3F, 0xFF, 0xC0, 0x00, 0x03, 0xFF, 0xFF, 0xFF, + 0xFF, 0x80, 0x00, 0x03, 0xFF, 0xFC, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, + 0xF8, 0x00, 0x00, 0x1F, 0xFF, 0xC0, 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, + 0x80, 0x00, 0x01, 0xFF, 0xFC, 0x00, 0x00, 0x3F, 0xFF, 0xF0, 0xFF, 0xFF, + 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00, + 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, + 0xF0, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xF8, 0x00, 0x00, 0x00, + 0x1F, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, + 0xFF, 0x00, 0x00, 0x00, 0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x00, + 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0xFF, + 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x00, 0x00, + 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xFF, + 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x00, + 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x07, 0xFF, 0xFF, + 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x00, + 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, + 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x1F, 0xFF, + 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, + 0x00, 0x00, 0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x00, 0x00, 0x03, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0x80, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x7F, + 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, + 0xF8, 0x00, 0x00, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x00, 0x00, 0x0F, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x07, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0x80, 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0x00, 0x01, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xF8, 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x00, 0x00, + 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x1F, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0x80, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0x00, + 0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x03, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFC, 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x00, + 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x7F, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, + 0x00, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x0F, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, + 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x01, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xE0, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x3F, 0xFF, + 0xFF, 0xFF, 0xFB, 0xFF, 0xFC, 0x00, 0x1F, 0xFF, 0xFF, 0xFF, 0xFD, 0xFF, + 0xFE, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0x00, 0x07, 0xFF, + 0xFF, 0xFF, 0xFF, 0x3F, 0xFF, 0xC0, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0x9F, + 0xFF, 0xE0, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xCF, 0xFF, 0xF0, 0x00, 0x7F, + 0xFF, 0xFF, 0xFF, 0xE3, 0xFF, 0xFC, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xF9, + 0xFF, 0xFE, 0x00, 0x1F, 0xFF, 0xFF, 0xFF, 0xFC, 0xFF, 0xFF, 0x00, 0x0F, + 0xFF, 0xFF, 0xFF, 0xFE, 0x3F, 0xFF, 0xC0, 0x07, 0xFF, 0xFF, 0xFF, 0xFF, + 0x1F, 0xFF, 0xE0, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0x8F, 0xFF, 0xF0, 0x01, + 0xFF, 0xFF, 0xFF, 0xFF, 0xC3, 0xFF, 0xFC, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, + 0xE1, 0xFF, 0xFE, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xF0, 0xFF, 0xFF, 0x00, + 0x3F, 0xFF, 0xFF, 0xFF, 0xF8, 0x3F, 0xFF, 0xC0, 0x1F, 0xFF, 0xFF, 0xFF, + 0xFC, 0x1F, 0xFF, 0xE0, 0x0F, 0xFF, 0xFF, 0xFF, 0xFE, 0x0F, 0xFF, 0xF0, + 0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0x03, 0xFF, 0xFC, 0x03, 0xFF, 0xFF, 0xFF, + 0xFF, 0x81, 0xFF, 0xFE, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0xFF, 0xFF, + 0x80, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0x3F, 0xFF, 0xC0, 0x7F, 0xFF, 0xFF, + 0xFF, 0xF0, 0x1F, 0xFF, 0xE0, 0x3F, 0xFF, 0xFF, 0xFF, 0xF8, 0x0F, 0xFF, + 0xF8, 0x1F, 0xFF, 0xFF, 0xFF, 0xFC, 0x03, 0xFF, 0xFC, 0x0F, 0xFF, 0xFF, + 0xFF, 0xFE, 0x01, 0xFF, 0xFE, 0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, + 0xFF, 0x83, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x3F, 0xFF, 0xC1, 0xFF, 0xFF, + 0xFF, 0xFF, 0xC0, 0x1F, 0xFF, 0xE0, 0x7F, 0xFF, 0xFF, 0xFF, 0xE0, 0x0F, + 0xFF, 0xF8, 0x3F, 0xFF, 0xFF, 0xFF, 0xF0, 0x03, 0xFF, 0xFC, 0x1F, 0xFF, + 0xFF, 0xFF, 0xF8, 0x01, 0xFF, 0xFE, 0x0F, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, + 0xFF, 0xFF, 0x87, 0xFF, 0xFF, 0xFF, 0xFE, 0x00, 0x3F, 0xFF, 0xC3, 0xFF, + 0xFF, 0xFF, 0xFF, 0x00, 0x1F, 0xFF, 0xE1, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, + 0x0F, 0xFF, 0xF8, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x03, 0xFF, 0xFC, 0x7F, + 0xFF, 0xFF, 0xFF, 0xE0, 0x01, 0xFF, 0xFE, 0x3F, 0xFF, 0xFF, 0xFF, 0xF0, + 0x00, 0xFF, 0xFF, 0x9F, 0xFF, 0xFF, 0xFF, 0xF8, 0x00, 0x3F, 0xFF, 0xCF, + 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x1F, 0xFF, 0xE7, 0xFF, 0xFF, 0xFF, 0xFE, + 0x00, 0x0F, 0xFF, 0xFB, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x03, 0xFF, 0xFD, + 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x01, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, + 0xC0, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0x00, 0x3F, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xF8, 0x00, 0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x03, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x3F, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xE0, 0x00, 0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x03, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFC, 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x00, 0x00, + 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x1F, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0x80, 0x00, 0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, + 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0x00, 0x01, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x00, + 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x00, 0x1F, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFE, 0x00, 0x00, 0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, + 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x01, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, + 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x1F, 0xFF, + 0xFF, 0xFF, 0xFF, 0xF8, 0x00, 0x00, 0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, + 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x00, 0x00, 0x01, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, + 0x80, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x1F, + 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x07, 0xFF, 0xFF, 0xFF, 0xFF, + 0xF0, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x00, 0x00, 0x01, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, + 0xFE, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, + 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x07, 0xFF, 0xFF, 0xFF, + 0xFF, 0xC0, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0x00, 0x00, + 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xFF, + 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x00, + 0x00, 0x1F, 0xFF, 0xFF, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x07, 0xFF, 0xFF, + 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x00, + 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x7F, 0xFF, + 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, + 0x00, 0x00, 0x1F, 0xFF, 0xFF, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x07, 0xFF, + 0xFF, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xFE, 0x00, + 0x00, 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x7F, + 0xFE, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, 0x1F, + 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0xF8, 0x00, + 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x3F, 0xFF, + 0xFF, 0xFF, 0xFC, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x00, + 0x00, 0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x00, 0x00, 0x1F, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFE, 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x00, + 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x00, 0x03, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFC, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, + 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xF8, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x03, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xE0, 0x1F, 0xFF, 0xFF, 0xE0, 0x1F, 0xFF, 0xFF, 0xE0, 0x7F, + 0xFF, 0xFF, 0x00, 0x0F, 0xFF, 0xFF, 0xC0, 0xFF, 0xFF, 0xFC, 0x00, 0x0F, + 0xFF, 0xFF, 0x81, 0xFF, 0xFF, 0xF0, 0x00, 0x0F, 0xFF, 0xFF, 0x83, 0xFF, + 0xFF, 0xC0, 0x00, 0x1F, 0xFF, 0xFF, 0x0F, 0xFF, 0xFF, 0x80, 0x00, 0x1F, + 0xFF, 0xFE, 0x1F, 0xFF, 0xFE, 0x00, 0x00, 0x3F, 0xFF, 0xFC, 0x3F, 0xFF, + 0xFC, 0x00, 0x00, 0x7F, 0xFF, 0xFC, 0x7F, 0xFF, 0xF8, 0x00, 0x00, 0x7F, + 0xFF, 0xF9, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0xFF, 0xFF, 0xF3, 0xFF, 0xFF, + 0xC0, 0x00, 0x01, 0xFF, 0xFF, 0xE7, 0xFF, 0xFF, 0x80, 0x00, 0x03, 0xFF, + 0xFF, 0xCF, 0xFF, 0xFF, 0x00, 0x00, 0x07, 0xFF, 0xFF, 0x9F, 0xFF, 0xFE, + 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0x3F, 0xFF, 0xFC, 0x00, 0x00, 0x0F, 0xFF, + 0xFE, 0x7F, 0xFF, 0xF8, 0x00, 0x00, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, + 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x7F, 0xFF, + 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, + 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x00, 0x00, 0x03, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFC, 0x00, 0x00, 0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x00, + 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x1F, 0xFF, 0xFF, + 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, + 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x00, 0x00, + 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x00, 0x07, 0xFF, 0xFF, 0xFF, + 0xFF, 0xF8, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x00, + 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, + 0xFF, 0xC0, 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x00, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFE, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x00, 0x07, + 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, + 0xF0, 0x00, 0x00, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x3F, + 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, + 0x80, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x01, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFE, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, + 0x00, 0x00, 0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x00, 0x00, 0x0F, 0xFF, + 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, + 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x7F, 0xFF, + 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, + 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x00, 0x00, 0x03, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFC, 0x00, 0x00, 0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x00, + 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x1F, 0xFF, 0xFF, + 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, + 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x00, 0x00, + 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x00, 0x07, 0xFF, 0xFF, 0xFF, + 0xFF, 0xF8, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x00, + 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, + 0xFF, 0xC0, 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x00, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFE, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x00, 0x07, + 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, + 0xF0, 0x00, 0x00, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x3F, + 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, + 0x80, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x01, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFE, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, + 0x00, 0x00, 0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x00, 0x00, 0x0F, 0xFF, + 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, + 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x7F, 0xFF, + 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, + 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x00, 0x00, 0x03, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFC, 0x00, 0x00, 0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x00, + 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x1F, 0xFF, 0xFF, + 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, + 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x00, 0x00, + 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x00, 0x07, 0xFF, 0xFF, 0xFF, + 0xFF, 0xF8, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x00, + 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, + 0xFF, 0xC0, 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x00, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFE, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x00, 0x07, + 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0x7F, 0xFF, + 0xF0, 0x00, 0x00, 0x1F, 0xFF, 0xFE, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x3F, + 0xFF, 0xF9, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x7F, 0xFF, 0xF3, 0xFF, 0xFF, + 0xC0, 0x00, 0x01, 0xFF, 0xFF, 0xE7, 0xFF, 0xFF, 0x80, 0x00, 0x03, 0xFF, + 0xFF, 0xCF, 0xFF, 0xFF, 0x00, 0x00, 0x07, 0xFF, 0xFF, 0x9F, 0xFF, 0xFE, + 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0x3F, 0xFF, 0xFC, 0x00, 0x00, 0x1F, 0xFF, + 0xFE, 0x3F, 0xFF, 0xF8, 0x00, 0x00, 0x3F, 0xFF, 0xFC, 0x7F, 0xFF, 0xF8, + 0x00, 0x00, 0xFF, 0xFF, 0xF0, 0xFF, 0xFF, 0xF0, 0x00, 0x01, 0xFF, 0xFF, + 0xE1, 0xFF, 0xFF, 0xE0, 0x00, 0x03, 0xFF, 0xFF, 0xC1, 0xFF, 0xFF, 0xE0, + 0x00, 0x0F, 0xFF, 0xFF, 0x83, 0xFF, 0xFF, 0xC0, 0x00, 0x1F, 0xFF, 0xFE, + 0x07, 0xFF, 0xFF, 0xC0, 0x00, 0x7F, 0xFF, 0xFC, 0x0F, 0xFF, 0xFF, 0xC0, + 0x01, 0xFF, 0xFF, 0xF8, 0x0F, 0xFF, 0xFF, 0xE0, 0x07, 0xFF, 0xFF, 0xE0, + 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x1F, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0x80, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x00, + 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xF0, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0x00, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFE, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x00, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xC0, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, + 0xE0, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, + 0x3F, 0xFF, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0x80, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xC0, 0x00, 0x00, 0x00, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, + 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0x00, 0x3F, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xE0, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, + 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x0F, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0x80, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xF8, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x3F, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0x83, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x0F, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x3F, 0xFF, 0xFC, 0x00, 0x3F, 0xFF, + 0xFF, 0xF0, 0xFF, 0xFF, 0xF0, 0x00, 0x1F, 0xFF, 0xFF, 0xC3, 0xFF, 0xFF, + 0xC0, 0x00, 0x1F, 0xFF, 0xFF, 0x8F, 0xFF, 0xFF, 0x00, 0x00, 0x3F, 0xFF, + 0xFE, 0x3F, 0xFF, 0xFC, 0x00, 0x00, 0xFF, 0xFF, 0xF8, 0xFF, 0xFF, 0xF0, + 0x00, 0x01, 0xFF, 0xFF, 0xF3, 0xFF, 0xFF, 0xC0, 0x00, 0x07, 0xFF, 0xFF, + 0xCF, 0xFF, 0xFF, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0x3F, 0xFF, 0xFC, 0x00, + 0x00, 0x3F, 0xFF, 0xFC, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0xFF, 0xFF, 0xF3, + 0xFF, 0xFF, 0xC0, 0x00, 0x03, 0xFF, 0xFF, 0xEF, 0xFF, 0xFF, 0x00, 0x00, + 0x07, 0xFF, 0xFF, 0xBF, 0xFF, 0xFC, 0x00, 0x00, 0x1F, 0xFF, 0xFE, 0xFF, + 0xFF, 0xF0, 0x00, 0x00, 0x7F, 0xFF, 0xFB, 0xFF, 0xFF, 0xC0, 0x00, 0x01, + 0xFF, 0xFF, 0xEF, 0xFF, 0xFF, 0x00, 0x00, 0x07, 0xFF, 0xFF, 0xBF, 0xFF, + 0xFC, 0x00, 0x00, 0x1F, 0xFF, 0xFE, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x7F, + 0xFF, 0xFB, 0xFF, 0xFF, 0xC0, 0x00, 0x01, 0xFF, 0xFF, 0xEF, 0xFF, 0xFF, + 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xBF, 0xFF, 0xFC, 0x00, 0x00, 0x0F, 0xFF, + 0xFE, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, + 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x03, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFC, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, + 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x00, + 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, + 0xFF, 0xC0, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x03, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, + 0xF0, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, + 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x3F, 0xFF, + 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0xFF, 0xFF, 0xEF, 0xFF, 0xFF, 0x00, + 0x00, 0x03, 0xFF, 0xFF, 0xBF, 0xFF, 0xFC, 0x00, 0x00, 0x0F, 0xFF, 0xFE, + 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x7F, 0xFF, 0xFB, 0xFF, 0xFF, 0xC0, 0x00, + 0x01, 0xFF, 0xFF, 0xEF, 0xFF, 0xFF, 0x00, 0x00, 0x07, 0xFF, 0xFF, 0xBF, + 0xFF, 0xFC, 0x00, 0x00, 0x1F, 0xFF, 0xFE, 0xFF, 0xFF, 0xF0, 0x00, 0x00, + 0x7F, 0xFF, 0xFB, 0xFF, 0xFF, 0xC0, 0x00, 0x01, 0xFF, 0xFF, 0xEF, 0xFF, + 0xFF, 0x00, 0x00, 0x07, 0xFF, 0xFF, 0xBF, 0xFF, 0xFC, 0x00, 0x00, 0x1F, + 0xFF, 0xFE, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x7F, 0xFF, 0xF3, 0xFF, 0xFF, + 0xC0, 0x00, 0x03, 0xFF, 0xFF, 0xCF, 0xFF, 0xFF, 0x00, 0x00, 0x0F, 0xFF, + 0xFF, 0x3F, 0xFF, 0xFC, 0x00, 0x00, 0x3F, 0xFF, 0xFC, 0xFF, 0xFF, 0xF0, + 0x00, 0x01, 0xFF, 0xFF, 0xF3, 0xFF, 0xFF, 0xC0, 0x00, 0x07, 0xFF, 0xFF, + 0x8F, 0xFF, 0xFF, 0x00, 0x00, 0x3F, 0xFF, 0xFE, 0x3F, 0xFF, 0xFC, 0x00, + 0x00, 0xFF, 0xFF, 0xF8, 0xFF, 0xFF, 0xF0, 0x00, 0x07, 0xFF, 0xFF, 0xE3, + 0xFF, 0xFF, 0xC0, 0x00, 0x7F, 0xFF, 0xFF, 0x0F, 0xFF, 0xFF, 0x00, 0x07, + 0xFF, 0xFF, 0xFC, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x83, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFE, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x3F, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFE, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x0F, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, + 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x03, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0x80, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, + 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFE, 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0x00, 0x0F, + 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x00, 0x00, 0x3F, 0xFF, 0xFC, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x03, 0xFF, + 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x3F, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, + 0xF0, 0x00, 0x00, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x00, + 0x00, 0x0F, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xFC, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, + 0x03, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xC0, 0x00, + 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, + 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, + 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFF, + 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xFC, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x03, 0xFF, 0xFF, + 0xC0, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x3F, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xF0, + 0x00, 0x00, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00, + 0x0F, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xFC, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x03, + 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, + 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xC0, 0x00, 0x00, + 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, + 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, + 0x00, 0x03, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFF, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xC0, + 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x3F, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xF0, 0x00, + 0x00, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x0F, + 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xFC, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x03, 0xFF, + 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x3F, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, + 0xF0, 0x00, 0x00, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x00, + 0x00, 0x0F, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xFC, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, + 0x03, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0x80, 0x00, + 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x01, 0xFF, + 0xFF, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, + 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x00, 0x01, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFE, 0x00, 0x00, 0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x00, + 0x00, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x00, 0x00, 0x7F, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFE, 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x00, + 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFC, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x00, + 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xF0, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x0F, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0x1F, 0xFF, 0xFF, 0xE0, 0x1F, + 0xFF, 0xFF, 0xE0, 0x7F, 0xFF, 0xFF, 0x00, 0x0F, 0xFF, 0xFF, 0xC0, 0xFF, + 0xFF, 0xFC, 0x00, 0x0F, 0xFF, 0xFF, 0x81, 0xFF, 0xFF, 0xF0, 0x00, 0x0F, + 0xFF, 0xFF, 0x83, 0xFF, 0xFF, 0xC0, 0x00, 0x1F, 0xFF, 0xFF, 0x0F, 0xFF, + 0xFF, 0x80, 0x00, 0x1F, 0xFF, 0xFE, 0x1F, 0xFF, 0xFE, 0x00, 0x00, 0x3F, + 0xFF, 0xFC, 0x3F, 0xFF, 0xFC, 0x00, 0x00, 0x7F, 0xFF, 0xFC, 0x7F, 0xFF, + 0xF8, 0x00, 0x00, 0x7F, 0xFF, 0xF9, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0xFF, + 0xFF, 0xF3, 0xFF, 0xFF, 0xC0, 0x00, 0x01, 0xFF, 0xFF, 0xE7, 0xFF, 0xFF, + 0x80, 0x00, 0x03, 0xFF, 0xFF, 0xCF, 0xFF, 0xFF, 0x00, 0x00, 0x07, 0xFF, + 0xFF, 0x9F, 0xFF, 0xFE, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0x3F, 0xFF, 0xFC, + 0x00, 0x00, 0x0F, 0xFF, 0xFE, 0x7F, 0xFF, 0xF8, 0x00, 0x00, 0x1F, 0xFF, + 0xFF, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, + 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x00, + 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x00, 0x07, 0xFF, 0xFF, + 0xFF, 0xFF, 0xF8, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, + 0x00, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x3F, 0xFF, 0xFF, + 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x00, + 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFE, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x00, + 0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, + 0xFF, 0xF0, 0x00, 0x00, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0x00, 0x00, + 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, + 0xFF, 0x80, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x01, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFC, 0x00, 0x00, 0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x00, 0x00, 0x0F, + 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, + 0xE0, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x7F, + 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0x00, 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x00, 0x00, 0x03, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x00, 0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, + 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x1F, 0xFF, + 0xFF, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, + 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x00, + 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x00, 0x07, 0xFF, 0xFF, + 0xFF, 0xFF, 0xF8, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, + 0x00, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x3F, 0xFF, 0xFF, + 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x00, + 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFE, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x00, + 0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, + 0xFF, 0xF0, 0x00, 0x00, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0x00, 0x00, + 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, + 0xFF, 0x80, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x01, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFC, 0x00, 0x00, 0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x00, 0x00, 0x0F, + 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, + 0xE0, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x7F, + 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0x00, 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x00, 0x00, 0x03, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x00, 0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, + 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x1F, 0xFF, + 0xFF, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, + 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x00, + 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x00, 0x07, 0xFF, 0xFF, + 0xFF, 0xFF, 0xF8, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, + 0x00, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x3F, 0xFF, 0xFF, + 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x00, + 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFE, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x00, + 0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, + 0xFF, 0xF0, 0x00, 0x00, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0x00, 0x00, + 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, + 0xFF, 0x80, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x01, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFC, 0x00, 0x00, 0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x00, 0x00, 0x0F, + 0xFF, 0xFF, 0x7F, 0xFF, 0xF0, 0x00, 0x00, 0x1F, 0xFF, 0xFE, 0xFF, 0xFF, + 0xF0, 0x00, 0x00, 0x3F, 0xFF, 0xF9, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x7F, + 0xFF, 0xF3, 0xFF, 0xFF, 0xC0, 0x00, 0x01, 0xFF, 0xFF, 0xE7, 0xFF, 0xFF, + 0x80, 0x00, 0x03, 0xFF, 0xFF, 0xCF, 0xFF, 0xFF, 0x00, 0x00, 0x07, 0xFF, + 0xFF, 0x9F, 0xFF, 0xFE, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0x3F, 0xFF, 0xFC, + 0x00, 0x00, 0x1F, 0xFF, 0xFE, 0x3F, 0xFF, 0xF8, 0x00, 0x00, 0x3F, 0xFF, + 0xFC, 0x7F, 0xFF, 0xF8, 0x00, 0x00, 0xFF, 0xFF, 0xF0, 0xFF, 0xFF, 0xF0, + 0x00, 0x01, 0xFF, 0xFF, 0xE1, 0xFF, 0xFF, 0xE0, 0x00, 0x03, 0xFF, 0xFF, + 0xC1, 0xFF, 0xFF, 0xE0, 0x00, 0x0F, 0xFF, 0xFF, 0x83, 0xFF, 0xFF, 0xC0, + 0x00, 0x1F, 0xFF, 0xFE, 0x07, 0xFF, 0xFF, 0xC0, 0x00, 0x7F, 0xFF, 0xFC, + 0x0F, 0xFF, 0xFF, 0xC0, 0x01, 0xFF, 0xFF, 0xF8, 0x0F, 0xFF, 0xFF, 0xE0, + 0x07, 0xFF, 0xFF, 0xE0, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, + 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x3F, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFE, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, + 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xE0, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x00, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFC, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x00, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x00, 0x00, + 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, + 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x00, + 0x0F, 0xFF, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xF8, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x3F, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xF8, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x3F, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xF0, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x3F, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xF0, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x3F, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xF0, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x7F, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0x80, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x7F, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xC0, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x7C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xF0, 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x00, 0x03, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0x80, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x1F, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0x80, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x07, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFC, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x3F, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x7F, 0xFF, 0xF8, 0x00, 0x3F, 0xFF, 0xFF, + 0xF0, 0xFF, 0xFF, 0xF0, 0x00, 0x07, 0xFF, 0xFF, 0xF1, 0xFF, 0xFF, 0xE0, + 0x00, 0x07, 0xFF, 0xFF, 0xE3, 0xFF, 0xFF, 0xC0, 0x00, 0x07, 0xFF, 0xFF, + 0xC7, 0xFF, 0xFF, 0x80, 0x00, 0x07, 0xFF, 0xFF, 0x8F, 0xFF, 0xFF, 0x00, + 0x00, 0x0F, 0xFF, 0xFF, 0x1F, 0xFF, 0xFE, 0x00, 0x00, 0x1F, 0xFF, 0xFF, + 0x3F, 0xFF, 0xFC, 0x00, 0x00, 0x1F, 0xFF, 0xFE, 0x7F, 0xFF, 0xF8, 0x00, + 0x00, 0x3F, 0xFF, 0xFC, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x7F, 0xFF, 0xF9, + 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0xFF, 0xFF, 0xF3, 0xFF, 0xFF, 0xC0, 0x00, + 0x01, 0xFF, 0xFF, 0xE7, 0xFF, 0xFF, 0x80, 0x00, 0x03, 0xFF, 0xFF, 0xCF, + 0xFF, 0xFF, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0x9F, 0xFF, 0xFE, 0x00, 0x00, + 0x07, 0xFF, 0xFF, 0x3F, 0xFF, 0xFC, 0x00, 0x00, 0x0F, 0xFF, 0xFE, 0x7F, + 0xFF, 0xF8, 0x00, 0x00, 0x1F, 0xFF, 0xFC, 0xFF, 0xFF, 0xF0, 0x00, 0x00, + 0x3F, 0xFF, 0xF9, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x7F, 0xFF, 0xF3, 0xFF, + 0xFF, 0xC0, 0x00, 0x00, 0xFF, 0xFF, 0xF7, 0xFF, 0xFF, 0x80, 0x00, 0x01, + 0xFF, 0xFF, 0xEF, 0xFF, 0xFF, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xDF, 0xFF, + 0xFE, 0x00, 0x00, 0x07, 0xFF, 0xFF, 0xBF, 0xFF, 0xFC, 0x00, 0x00, 0x0F, + 0xFF, 0xFF, 0x7F, 0xFF, 0xF8, 0x00, 0x00, 0x1F, 0xFF, 0xFE, 0xFF, 0xFF, + 0xF0, 0x00, 0x00, 0x3F, 0xFF, 0xFD, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x7F, + 0xFF, 0xFB, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0xFF, 0xFF, 0xF7, 0xFF, 0xFF, + 0x80, 0x00, 0x01, 0xFF, 0xFF, 0xCF, 0xFF, 0xFF, 0x00, 0x00, 0x03, 0xFF, + 0xFF, 0x9F, 0xFF, 0xFE, 0x00, 0x00, 0x07, 0xFF, 0xFF, 0x3F, 0xFF, 0xFC, + 0x00, 0x00, 0x0F, 0xFF, 0xFE, 0x7F, 0xFF, 0xF8, 0x00, 0x00, 0x1F, 0xFF, + 0xFC, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x7F, 0xFF, 0xF9, 0xFF, 0xFF, 0xE0, + 0x00, 0x00, 0xFF, 0xFF, 0xF3, 0xFF, 0xFF, 0xC0, 0x00, 0x01, 0xFF, 0xFF, + 0xE7, 0xFF, 0xFF, 0x80, 0x00, 0x03, 0xFF, 0xFF, 0xCF, 0xFF, 0xFF, 0x00, + 0x00, 0x07, 0xFF, 0xFF, 0x9F, 0xFF, 0xFE, 0x00, 0x00, 0x0F, 0xFF, 0xFF, + 0x3F, 0xFF, 0xFC, 0x00, 0x00, 0x1F, 0xFF, 0xFC, 0x7F, 0xFF, 0xF8, 0x00, + 0x00, 0x3F, 0xFF, 0xF8, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0xFF, 0xFF, 0xF1, + 0xFF, 0xFF, 0xE0, 0x00, 0x01, 0xFF, 0xFF, 0xE3, 0xFF, 0xFF, 0xC0, 0x00, + 0x03, 0xFF, 0xFF, 0x87, 0xFF, 0xFF, 0x80, 0x00, 0x0F, 0xFF, 0xFF, 0x0F, + 0xFF, 0xFF, 0x00, 0x00, 0x1F, 0xFF, 0xFE, 0x1F, 0xFF, 0xFE, 0x00, 0x00, + 0x7F, 0xFF, 0xF8, 0x3F, 0xFF, 0xFC, 0x00, 0x03, 0xFF, 0xFF, 0xF0, 0x7F, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0x81, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x03, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xE0, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x1F, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xE0, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0x00, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xF0, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x07, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xF0, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x3F, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0x7F, 0xFF, 0xF8, 0x00, 0x3F, 0xFF, 0xFF, + 0xE0, 0xFF, 0xFF, 0xF0, 0x00, 0x0F, 0xFF, 0xFF, 0xC1, 0xFF, 0xFF, 0xE0, + 0x00, 0x07, 0xFF, 0xFF, 0x83, 0xFF, 0xFF, 0xC0, 0x00, 0x07, 0xFF, 0xFF, + 0x87, 0xFF, 0xFF, 0x80, 0x00, 0x07, 0xFF, 0xFF, 0x0F, 0xFF, 0xFF, 0x00, + 0x00, 0x0F, 0xFF, 0xFE, 0x1F, 0xFF, 0xFE, 0x00, 0x00, 0x0F, 0xFF, 0xFC, + 0x3F, 0xFF, 0xFC, 0x00, 0x00, 0x1F, 0xFF, 0xFC, 0x7F, 0xFF, 0xF8, 0x00, + 0x00, 0x3F, 0xFF, 0xF8, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x7F, 0xFF, 0xF1, + 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0xFF, 0xFF, 0xE3, 0xFF, 0xFF, 0xC0, 0x00, + 0x01, 0xFF, 0xFF, 0xC7, 0xFF, 0xFF, 0x80, 0x00, 0x01, 0xFF, 0xFF, 0x8F, + 0xFF, 0xFF, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0x9F, 0xFF, 0xFE, 0x00, 0x00, + 0x07, 0xFF, 0xFF, 0x3F, 0xFF, 0xFC, 0x00, 0x00, 0x0F, 0xFF, 0xFE, 0x7F, + 0xFF, 0xF8, 0x00, 0x00, 0x1F, 0xFF, 0xFC, 0xFF, 0xFF, 0xF0, 0x00, 0x00, + 0x3F, 0xFF, 0xF9, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x7F, 0xFF, 0xF3, 0xFF, + 0xFF, 0xC0, 0x00, 0x00, 0xFF, 0xFF, 0xE7, 0xFF, 0xFF, 0x80, 0x00, 0x01, + 0xFF, 0xFF, 0xCF, 0xFF, 0xFF, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0x9F, 0xFF, + 0xFE, 0x00, 0x00, 0x07, 0xFF, 0xFF, 0x3F, 0xFF, 0xFC, 0x00, 0x00, 0x0F, + 0xFF, 0xFE, 0x7F, 0xFF, 0xF8, 0x00, 0x00, 0x1F, 0xFF, 0xFC, 0xFF, 0xFF, + 0xF0, 0x00, 0x00, 0x3F, 0xFF, 0xF9, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x7F, + 0xFF, 0xF3, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0xFF, 0xFF, 0xF7, 0xFF, 0xFF, + 0x80, 0x00, 0x01, 0xFF, 0xFF, 0xEF, 0xFF, 0xFF, 0x00, 0x00, 0x03, 0xFF, + 0xFF, 0xDF, 0xFF, 0xFE, 0x00, 0x00, 0x07, 0xFF, 0xFF, 0xBF, 0xFF, 0xFC, + 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0x7F, 0xFF, 0xF8, 0x00, 0x00, 0x1F, 0xFF, + 0xFE, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x3F, 0xFF, 0xFD, 0xFF, 0xFF, 0xE0, + 0x00, 0x00, 0x7F, 0xFF, 0xFB, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0xFF, 0xFF, + 0xF7, 0xFF, 0xFF, 0x80, 0x00, 0x01, 0xFF, 0xFF, 0xEF, 0xFF, 0xFF, 0x00, + 0x00, 0x03, 0xFF, 0xFF, 0xDF, 0xFF, 0xFE, 0x00, 0x00, 0x07, 0xFF, 0xFF, + 0xBF, 0xFF, 0xFC, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0x7F, 0xFF, 0xF8, 0x00, + 0x00, 0x1F, 0xFF, 0xFE, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x3F, 0xFF, 0xFD, + 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x7F, 0xFF, 0xFB, 0xFF, 0xFF, 0xC0, 0x00, + 0x00, 0xFF, 0xFF, 0xF7, 0xFF, 0xFF, 0x80, 0x00, 0x01, 0xFF, 0xFF, 0xEF, + 0xFF, 0xFF, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xDF, 0xFF, 0xFE, 0x00, 0x00, + 0x07, 0xFF, 0xFF, 0xBF, 0xFF, 0xFC, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0x7F, + 0xFF, 0xF8, 0x00, 0x00, 0x1F, 0xFF, 0xFE, 0xFF, 0xFF, 0xF0, 0x00, 0x00, + 0x3F, 0xFF, 0xFD, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x7F, 0xFF, 0xFB, 0xFF, + 0xFF, 0xC0, 0x00, 0x00, 0xFF, 0xFF, 0xF7, 0xFF, 0xFF, 0x80, 0x00, 0x01, + 0xFF, 0xFF, 0xEF, 0xFF, 0xFF, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xDF, 0xFF, + 0xFE, 0x00, 0x00, 0x07, 0xFF, 0xFF, 0xBF, 0xFF, 0xFC, 0x00, 0x00, 0x0F, + 0xFF, 0xFF, 0x7F, 0xFF, 0xF8, 0x00, 0x00, 0x1F, 0xFF, 0xFE, 0xFF, 0xFF, + 0xF0, 0x00, 0x00, 0x3F, 0xFF, 0xFD, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x7F, + 0xFF, 0xFB, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0xFF, 0xFF, 0xF7, 0xFF, 0xFF, + 0x80, 0x00, 0x01, 0xFF, 0xFF, 0xEF, 0xFF, 0xFF, 0x00, 0x00, 0x03, 0xFF, + 0xFF, 0xDF, 0xFF, 0xFE, 0x00, 0x00, 0x07, 0xFF, 0xFF, 0xBF, 0xFF, 0xFC, + 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0x7F, 0xFF, 0xF8, 0x00, 0x00, 0x1F, 0xFF, + 0xFE, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x3F, 0xFF, 0xFD, 0xFF, 0xFF, 0xE0, + 0x00, 0x00, 0x7F, 0xFF, 0xFB, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0xFF, 0xFF, + 0xF7, 0xFF, 0xFF, 0x80, 0x00, 0x01, 0xFF, 0xFF, 0xEF, 0xFF, 0xFF, 0x00, + 0x00, 0x01, 0xFF, 0xFF, 0xDF, 0xFF, 0xFE, 0x00, 0x00, 0x03, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFC, 0x00, 0x00, 0x07, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x07, + 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xFE, 0x00, 0x00, + 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xFF, + 0xFF, 0xF8, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x00, + 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x01, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0x80, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x00, 0x0F, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xF8, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, + 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xF8, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x3F, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x01, 0xFF, 0xFF, 0xFE, 0x01, 0xFF, + 0xFF, 0xF8, 0x0F, 0xFF, 0xFF, 0xC0, 0x07, 0xFF, 0xFF, 0xC0, 0xFF, 0xFF, + 0xF8, 0x00, 0x1F, 0xFF, 0xFF, 0x07, 0xFF, 0xFF, 0xC0, 0x00, 0x7F, 0xFF, + 0xF8, 0x3F, 0xFF, 0xFC, 0x00, 0x01, 0xFF, 0xFF, 0xC1, 0xFF, 0xFF, 0xC0, + 0x00, 0x0F, 0xFF, 0xFE, 0x0F, 0xFF, 0xFE, 0x00, 0x00, 0x7F, 0xFF, 0xF0, + 0xFF, 0xFF, 0xF0, 0x00, 0x01, 0xFF, 0xFF, 0xC7, 0xFF, 0xFF, 0x80, 0x00, + 0x0F, 0xFF, 0xFE, 0x3F, 0xFF, 0xF8, 0x00, 0x00, 0x7F, 0xFF, 0xF1, 0xFF, + 0xFF, 0xC0, 0x00, 0x03, 0xFF, 0xFF, 0x8F, 0xFF, 0xFE, 0x00, 0x00, 0x1F, + 0xFF, 0xFC, 0x7F, 0xFF, 0xF0, 0x00, 0x00, 0xFF, 0xFF, 0xE3, 0xFF, 0xFF, + 0x80, 0x00, 0x03, 0xFF, 0xFF, 0x1F, 0xFF, 0xFC, 0x00, 0x00, 0x1F, 0xFF, + 0xF8, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0xFF, 0xFF, 0xC7, 0xFF, 0xFF, 0x00, + 0x00, 0x07, 0xFF, 0xFE, 0x3F, 0xFF, 0xF8, 0x00, 0x00, 0x3F, 0xFF, 0xF9, + 0xFF, 0xFF, 0xC0, 0x00, 0x01, 0xFF, 0xFF, 0xCF, 0xFF, 0xFE, 0x00, 0x00, + 0x0F, 0xFF, 0xFE, 0x7F, 0xFF, 0xF0, 0x00, 0x00, 0x7F, 0xFF, 0xF3, 0xFF, + 0xFF, 0x80, 0x00, 0x03, 0xFF, 0xFF, 0x9F, 0xFF, 0xFC, 0x00, 0x00, 0x1F, + 0xFF, 0xFC, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0xFF, 0xFF, 0xE7, 0xFF, 0xFF, + 0x00, 0x00, 0x07, 0xFF, 0xFF, 0x3F, 0xFF, 0xFC, 0x00, 0x00, 0x3F, 0xFF, + 0xF9, 0xFF, 0xFF, 0xE0, 0x00, 0x01, 0xFF, 0xFF, 0xCF, 0xFF, 0xFF, 0x00, + 0x00, 0x0F, 0xFF, 0xFE, 0x7F, 0xFF, 0xFC, 0x00, 0x00, 0x7F, 0xFF, 0xF3, + 0xFF, 0xFF, 0xE0, 0x00, 0x03, 0xFF, 0xFF, 0x8F, 0xFF, 0xFF, 0x80, 0x00, + 0x1F, 0xFF, 0xFC, 0x7F, 0xFF, 0xFC, 0x00, 0x00, 0xFF, 0xFF, 0xE3, 0xFF, + 0xFF, 0xF0, 0x00, 0x07, 0xFF, 0xFF, 0x0F, 0xFF, 0xFF, 0xC0, 0x00, 0x3F, + 0xFF, 0xF8, 0x7F, 0xFF, 0xFF, 0x00, 0x01, 0xFF, 0xFF, 0xC3, 0xFF, 0xFF, + 0xFC, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x00, + 0x00, 0x7F, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0xFE, + 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x00, + 0x3F, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0x80, + 0x00, 0x00, 0x00, 0x07, 0xFF, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x3F, + 0xFF, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xE0, 0x00, + 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x1F, 0xFF, + 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xF8, 0x00, 0x00, + 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x07, 0xFF, 0xFF, + 0xFF, 0x80, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xFC, 0x00, 0x00, 0x00, + 0x00, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xFF, + 0xC0, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, + 0x3F, 0xFF, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xF0, + 0x00, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x0F, + 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xFC, 0x00, + 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x03, 0xFF, + 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xFE, 0x00, 0x00, + 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, + 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, + 0x00, 0x0F, 0xFF, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xFF, + 0xE0, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00, + 0x03, 0xFF, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xFF, 0xF0, + 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x01, + 0xFF, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x07, 0xFF, 0xFF, 0xF8, 0x00, + 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x7F, + 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xF8, 0x00, 0x00, + 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, + 0xFF, 0x00, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0xF8, 0xFF, 0xFF, 0xE0, + 0x00, 0x07, 0xFF, 0xFF, 0xC7, 0xFF, 0xFF, 0x00, 0x00, 0x3F, 0xFF, 0xFF, + 0x3F, 0xFF, 0xF8, 0x00, 0x00, 0xFF, 0xFF, 0xF9, 0xFF, 0xFF, 0xC0, 0x00, + 0x07, 0xFF, 0xFF, 0xCF, 0xFF, 0xFE, 0x00, 0x00, 0x1F, 0xFF, 0xFE, 0x7F, + 0xFF, 0xF0, 0x00, 0x00, 0xFF, 0xFF, 0xFB, 0xFF, 0xFF, 0x80, 0x00, 0x07, + 0xFF, 0xFF, 0xDF, 0xFF, 0xFC, 0x00, 0x00, 0x1F, 0xFF, 0xFE, 0xFF, 0xFF, + 0xE0, 0x00, 0x00, 0xFF, 0xFF, 0xF7, 0xFF, 0xFF, 0x00, 0x00, 0x07, 0xFF, + 0xFF, 0xBF, 0xFF, 0xF8, 0x00, 0x00, 0x1F, 0xFF, 0xFD, 0xFF, 0xFF, 0xC0, + 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x00, 0x00, 0x07, 0xFF, 0xFF, + 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x00, + 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, + 0xFF, 0xE0, 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x03, + 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x00, 0x00, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, + 0xC0, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x00, 0x00, 0x07, 0xFF, + 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, + 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x00, 0x00, 0x0F, 0xFF, 0xFF, + 0x7F, 0xFF, 0xF0, 0x00, 0x00, 0x7F, 0xFF, 0xFB, 0xFF, 0xFF, 0x80, 0x00, + 0x03, 0xFF, 0xFF, 0xDF, 0xFF, 0xFC, 0x00, 0x00, 0x1F, 0xFF, 0xFE, 0xFF, + 0xFF, 0xE0, 0x00, 0x00, 0xFF, 0xFF, 0xF7, 0xFF, 0xFF, 0x00, 0x00, 0x07, + 0xFF, 0xFF, 0x3F, 0xFF, 0xF8, 0x00, 0x00, 0x3F, 0xFF, 0xF9, 0xFF, 0xFF, + 0xC0, 0x00, 0x01, 0xFF, 0xFF, 0xCF, 0xFF, 0xFE, 0x00, 0x00, 0x0F, 0xFF, + 0xFE, 0x7F, 0xFF, 0xF8, 0x00, 0x00, 0x7F, 0xFF, 0xF1, 0xFF, 0xFF, 0xC0, + 0x00, 0x03, 0xFF, 0xFF, 0x8F, 0xFF, 0xFE, 0x00, 0x00, 0x3F, 0xFF, 0xFC, + 0x7F, 0xFF, 0xF8, 0x00, 0x01, 0xFF, 0xFF, 0xC3, 0xFF, 0xFF, 0xC0, 0x00, + 0x0F, 0xFF, 0xFE, 0x1F, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xF0, 0x7F, + 0xFF, 0xF8, 0x00, 0x0F, 0xFF, 0xFF, 0x83, 0xFF, 0xFF, 0xE0, 0x00, 0x7F, + 0xFF, 0xF8, 0x1F, 0xFF, 0xFF, 0xC0, 0x0F, 0xFF, 0xFF, 0xC0, 0x7F, 0xFF, + 0xFF, 0xE7, 0xFF, 0xFF, 0xFE, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xE0, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x7F, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xF8, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, + 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xC0, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x07, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0x00, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFE, 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0x00, 0x01, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFE, 0x00, 0x00, 0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, + 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x3F, 0xFF, + 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xF0, 0x00, 0x00, + 0x00, 0x00, 0x7F, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFC, + 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0x00, 0x00, 0x7F, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x03, 0xFF, 0xFF, + 0xC0, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x00, 0xFF, + 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x07, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00, + 0x3F, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0xE0, 0x00, 0x00, + 0x00, 0x0F, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xF8, 0x00, + 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xFE, + 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x07, 0xFF, + 0xFF, 0x80, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x01, + 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0x00, 0x00, 0x00, + 0x00, 0x7F, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xC0, 0x00, + 0x00, 0x00, 0x1F, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xF0, + 0x00, 0x00, 0x00, 0x07, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x3F, 0xFF, + 0xFC, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x0F, + 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xF8, 0x00, 0x00, 0x00, + 0x03, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xFE, 0x00, 0x00, + 0x00, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x07, 0xFF, 0xFF, 0x80, + 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFF, + 0xE0, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x7F, + 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x00, + 0x1F, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, + 0x00, 0x07, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xFC, 0x00, + 0x00, 0x00, 0x01, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFF, + 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x03, 0xFF, + 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x00, + 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x07, 0xFF, 0xFF, 0x80, 0x00, 0x00, + 0x00, 0x3F, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0xE0, 0x00, + 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xF8, + 0x00, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x1F, 0xFF, + 0xFE, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x07, + 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xFC, 0x00, 0x00, 0x00, + 0x01, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0x00, 0x00, + 0x00, 0x00, 0x7F, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xC0, + 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, + 0xF0, 0x00, 0x00, 0x00, 0x07, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x3F, + 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x00, + 0x0F, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xF8, 0x00, 0x00, + 0x00, 0x03, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xFE, 0x00, + 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x07, 0xFF, 0xFF, + 0x80, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x01, 0xFF, + 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, + 0x7F, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xC0, 0x00, 0x00, + 0x00, 0x1F, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xF0, 0x00, + 0x00, 0x00, 0x07, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xFC, + 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x0F, 0xFF, + 0xFF, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x03, + 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xFE, 0x00, 0x00, 0x00, + 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x07, 0xFF, 0xFF, 0x80, 0x00, + 0x00, 0x00, 0x3F, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0xE0, + 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, + 0xF8, 0x00, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x1F, + 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, + 0x07, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xFC, 0x00, 0x00, + 0x00, 0x01, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0x00, + 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x03, 0xFF, 0xFF, + 0xC0, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x00, 0xFF, + 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x07, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00, + 0x3F, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0xE0, 0x00, 0x00, + 0x00, 0x0F, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xF8, 0x00, + 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xFE, + 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x07, 0xFF, + 0xFF, 0x80, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x01, + 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0x00, 0x00, 0x00, + 0x00, 0x7F, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xC0, 0x00, + 0x00, 0x00, 0x1F, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xF0, + 0x00, 0x00, 0x00, 0x07, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x3F, 0xFF, + 0xFC, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x0F, + 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xF8, 0x00, 0x00, 0x00, + 0x03, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xFE, 0x00, 0x00, + 0x00, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x07, 0xFF, 0xFF, 0x80, + 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFF, + 0xE0, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x7F, + 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x00, + 0x1F, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, + 0x00, 0x07, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xFC, 0x00, + 0x00, 0x00, 0x01, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0xFF, 0xFF, 0xF0, 0x00, + 0x00, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x3F, 0xFF, 0xFF, + 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x00, + 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFE, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x00, + 0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, + 0xFF, 0xF0, 0x00, 0x00, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0x00, 0x00, + 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, + 0xFF, 0x80, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x01, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFC, 0x00, 0x00, 0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x00, 0x00, 0x0F, + 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, + 0xE0, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x7F, + 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0x00, 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x00, 0x00, 0x03, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x00, 0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, + 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x1F, 0xFF, + 0xFF, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, + 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x00, + 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x00, 0x07, 0xFF, 0xFF, + 0xFF, 0xFF, 0xF8, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, + 0x00, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x3F, 0xFF, 0xFF, + 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x00, + 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFE, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x00, + 0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, + 0xFF, 0xF0, 0x00, 0x00, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0x00, 0x00, + 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, + 0xFF, 0x80, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x01, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFC, 0x00, 0x00, 0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x00, 0x00, 0x0F, + 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, + 0xE0, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x7F, + 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0x00, 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x00, 0x00, 0x03, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x00, 0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, + 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x1F, 0xFF, + 0xFF, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, + 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x00, + 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x00, 0x07, 0xFF, 0xFF, + 0xFF, 0xFF, 0xF8, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, + 0x00, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x3F, 0xFF, 0xFF, + 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x00, + 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFE, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x00, + 0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, + 0xFF, 0xF0, 0x00, 0x00, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0x00, 0x00, + 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, + 0xFF, 0x80, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x01, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFC, 0x00, 0x00, 0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x00, 0x00, 0x0F, + 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, + 0xE0, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x7F, + 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0x00, 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x00, 0x00, 0x03, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x00, 0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, + 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x1F, 0xFF, + 0xFF, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, + 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x00, + 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x00, 0x07, 0xFF, 0xFF, + 0xFF, 0xFF, 0xF8, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, + 0x00, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x3F, 0xFF, 0xFF, + 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x00, + 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFE, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x00, + 0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, + 0xFF, 0xF0, 0x00, 0x00, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0x00, 0x00, + 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, + 0xFF, 0x80, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x01, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFC, 0x00, 0x00, 0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x00, 0x00, 0x0F, + 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, + 0xE0, 0x00, 0x00, 0x3F, 0xFF, 0xFB, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0xFF, + 0xFF, 0xF7, 0xFF, 0xFF, 0x80, 0x00, 0x01, 0xFF, 0xFF, 0xEF, 0xFF, 0xFF, + 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xDF, 0xFF, 0xFE, 0x00, 0x00, 0x07, 0xFF, + 0xFF, 0xBF, 0xFF, 0xFC, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0x7F, 0xFF, 0xF8, + 0x00, 0x00, 0x1F, 0xFF, 0xFE, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x3F, 0xFF, + 0xFD, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x7F, 0xFF, 0xFB, 0xFF, 0xFF, 0xC0, + 0x00, 0x00, 0xFF, 0xFF, 0xF7, 0xFF, 0xFF, 0x80, 0x00, 0x01, 0xFF, 0xFF, + 0xEF, 0xFF, 0xFF, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xCF, 0xFF, 0xFE, 0x00, + 0x00, 0x07, 0xFF, 0xFF, 0x9F, 0xFF, 0xFE, 0x00, 0x00, 0x0F, 0xFF, 0xFE, + 0x3F, 0xFF, 0xFC, 0x00, 0x00, 0x1F, 0xFF, 0xFC, 0x7F, 0xFF, 0xF8, 0x00, + 0x00, 0x7F, 0xFF, 0xF8, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0xFF, 0xFF, 0xF0, + 0xFF, 0xFF, 0xF0, 0x00, 0x01, 0xFF, 0xFF, 0xE1, 0xFF, 0xFF, 0xE0, 0x00, + 0x07, 0xFF, 0xFF, 0x83, 0xFF, 0xFF, 0xE0, 0x00, 0x1F, 0xFF, 0xFF, 0x07, + 0xFF, 0xFF, 0xE0, 0x00, 0x3F, 0xFF, 0xFE, 0x07, 0xFF, 0xFF, 0xE0, 0x01, + 0xFF, 0xFF, 0xFC, 0x0F, 0xFF, 0xFF, 0xF8, 0x1F, 0xFF, 0xFF, 0xF0, 0x1F, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0x80, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x3F, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xF8, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0x00, 0x7F, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x00, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xC0, 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x7F, + 0xFF, 0xFF, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xE0, + 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x07, + 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xF8, 0x00, 0x00, + 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFE, 0xFF, 0xFF, + 0xE0, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xFD, 0xFF, 0xFF, 0xC0, 0x00, 0x00, + 0x00, 0x3F, 0xFF, 0xFB, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x7F, 0xFF, + 0xF7, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xEF, 0xFF, 0xFE, + 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0x8F, 0xFF, 0xFE, 0x00, 0x00, 0x00, + 0x03, 0xFF, 0xFF, 0x1F, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFE, + 0x3F, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xFC, 0x7F, 0xFF, 0xF0, + 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xF8, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x00, + 0x7F, 0xFF, 0xF1, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xE1, + 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0x83, 0xFF, 0xFF, 0x80, + 0x00, 0x00, 0x03, 0xFF, 0xFF, 0x07, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x07, + 0xFF, 0xFE, 0x0F, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xFC, 0x1F, + 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xF8, 0x3F, 0xFF, 0xF8, 0x00, + 0x00, 0x00, 0x7F, 0xFF, 0xF0, 0x7F, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, + 0xFF, 0xC0, 0x7F, 0xFF, 0xE0, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0x80, 0xFF, + 0xFF, 0xE0, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0x01, 0xFF, 0xFF, 0xC0, 0x00, + 0x00, 0x07, 0xFF, 0xFE, 0x03, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x0F, 0xFF, + 0xFC, 0x07, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xF8, 0x0F, 0xFF, + 0xFE, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xF0, 0x0F, 0xFF, 0xFC, 0x00, 0x00, + 0x00, 0xFF, 0xFF, 0xC0, 0x1F, 0xFF, 0xFC, 0x00, 0x00, 0x01, 0xFF, 0xFF, + 0x80, 0x3F, 0xFF, 0xF8, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0x00, 0x7F, 0xFF, + 0xF0, 0x00, 0x00, 0x07, 0xFF, 0xFE, 0x00, 0xFF, 0xFF, 0xE0, 0x00, 0x00, + 0x0F, 0xFF, 0xFC, 0x01, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x3F, 0xFF, 0xF8, + 0x01, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x7F, 0xFF, 0xF0, 0x03, 0xFF, 0xFF, + 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xC0, 0x07, 0xFF, 0xFF, 0x00, 0x00, 0x01, + 0xFF, 0xFF, 0x80, 0x0F, 0xFF, 0xFE, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0x00, + 0x1F, 0xFF, 0xFC, 0x00, 0x00, 0x07, 0xFF, 0xFE, 0x00, 0x3F, 0xFF, 0xF8, + 0x00, 0x00, 0x0F, 0xFF, 0xFC, 0x00, 0x3F, 0xFF, 0xF0, 0x00, 0x00, 0x1F, + 0xFF, 0xF8, 0x00, 0x7F, 0xFF, 0xE0, 0x00, 0x00, 0x7F, 0xFF, 0xF0, 0x00, + 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0xFF, 0xFF, 0xC0, 0x01, 0xFF, 0xFF, 0xC0, + 0x00, 0x01, 0xFF, 0xFF, 0x80, 0x03, 0xFF, 0xFF, 0x80, 0x00, 0x03, 0xFF, + 0xFF, 0x00, 0x07, 0xFF, 0xFF, 0x00, 0x00, 0x07, 0xFF, 0xFE, 0x00, 0x07, + 0xFF, 0xFE, 0x00, 0x00, 0x0F, 0xFF, 0xFC, 0x00, 0x0F, 0xFF, 0xFC, 0x00, + 0x00, 0x1F, 0xFF, 0xF8, 0x00, 0x1F, 0xFF, 0xF8, 0x00, 0x00, 0x3F, 0xFF, + 0xE0, 0x00, 0x3F, 0xFF, 0xF8, 0x00, 0x00, 0xFF, 0xFF, 0xC0, 0x00, 0x7F, + 0xFF, 0xF0, 0x00, 0x01, 0xFF, 0xFF, 0x80, 0x00, 0xFF, 0xFF, 0xE0, 0x00, + 0x03, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xC0, 0x00, 0x07, 0xFF, 0xFE, + 0x00, 0x01, 0xFF, 0xFF, 0x80, 0x00, 0x0F, 0xFF, 0xFC, 0x00, 0x03, 0xFF, + 0xFF, 0x00, 0x00, 0x1F, 0xFF, 0xF8, 0x00, 0x07, 0xFF, 0xFE, 0x00, 0x00, + 0x3F, 0xFF, 0xE0, 0x00, 0x0F, 0xFF, 0xFE, 0x00, 0x00, 0x7F, 0xFF, 0xC0, + 0x00, 0x1F, 0xFF, 0xFC, 0x00, 0x01, 0xFF, 0xFF, 0x80, 0x00, 0x3F, 0xFF, + 0xF8, 0x00, 0x03, 0xFF, 0xFF, 0x00, 0x00, 0x3F, 0xFF, 0xF0, 0x00, 0x07, + 0xFF, 0xFE, 0x00, 0x00, 0x7F, 0xFF, 0xE0, 0x00, 0x0F, 0xFF, 0xFC, 0x00, + 0x00, 0xFF, 0xFF, 0xC0, 0x00, 0x1F, 0xFF, 0xF8, 0x00, 0x01, 0xFF, 0xFF, + 0xC0, 0x00, 0x3F, 0xFF, 0xE0, 0x00, 0x03, 0xFF, 0xFF, 0x80, 0x00, 0x7F, + 0xFF, 0xC0, 0x00, 0x07, 0xFF, 0xFF, 0x00, 0x01, 0xFF, 0xFF, 0x80, 0x00, + 0x07, 0xFF, 0xFE, 0x00, 0x03, 0xFF, 0xFF, 0x00, 0x00, 0x0F, 0xFF, 0xFC, + 0x00, 0x07, 0xFF, 0xFE, 0x00, 0x00, 0x1F, 0xFF, 0xF8, 0x00, 0x0F, 0xFF, + 0xFC, 0x00, 0x00, 0x3F, 0xFF, 0xF0, 0x00, 0x1F, 0xFF, 0xF8, 0x00, 0x00, + 0x7F, 0xFF, 0xF0, 0x00, 0x3F, 0xFF, 0xE0, 0x00, 0x00, 0xFF, 0xFF, 0xE0, + 0x00, 0x7F, 0xFF, 0xC0, 0x00, 0x00, 0xFF, 0xFF, 0xC0, 0x00, 0xFF, 0xFF, + 0x80, 0x00, 0x01, 0xFF, 0xFF, 0x80, 0x03, 0xFF, 0xFF, 0x00, 0x00, 0x03, + 0xFF, 0xFF, 0x00, 0x07, 0xFF, 0xFE, 0x00, 0x00, 0x07, 0xFF, 0xFE, 0x00, + 0x0F, 0xFF, 0xFC, 0x00, 0x00, 0x0F, 0xFF, 0xFC, 0x00, 0x1F, 0xFF, 0xF8, + 0x00, 0x00, 0x1F, 0xFF, 0xFC, 0x00, 0x3F, 0xFF, 0xE0, 0x00, 0x00, 0x1F, + 0xFF, 0xF8, 0x00, 0x7F, 0xFF, 0xC0, 0x00, 0x00, 0x3F, 0xFF, 0xF0, 0x00, + 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x7F, 0xFF, 0xE0, 0x01, 0xFF, 0xFF, 0x00, + 0x00, 0x00, 0xFF, 0xFF, 0xC0, 0x07, 0xFF, 0xFE, 0x00, 0x00, 0x01, 0xFF, + 0xFF, 0x80, 0x0F, 0xFF, 0xFC, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0x00, 0x1F, + 0xFF, 0xF0, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0x00, 0x3F, 0xFF, 0xE0, 0x00, + 0x00, 0x07, 0xFF, 0xFE, 0x00, 0x7F, 0xFF, 0xC0, 0x00, 0x00, 0x0F, 0xFF, + 0xFC, 0x00, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x1F, 0xFF, 0xF8, 0x01, 0xFF, + 0xFF, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xF0, 0x03, 0xFF, 0xFE, 0x00, 0x00, + 0x00, 0x7F, 0xFF, 0xE0, 0x0F, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0xFF, 0xFF, + 0xC0, 0x1F, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xC0, 0x3F, 0xFF, + 0xE0, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0x80, 0x7F, 0xFF, 0xC0, 0x00, 0x00, + 0x03, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x07, 0xFF, 0xFE, + 0x01, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFC, 0x03, 0xFF, 0xFE, + 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xF8, 0x07, 0xFF, 0xFC, 0x00, 0x00, 0x00, + 0x1F, 0xFF, 0xF0, 0x0F, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xF0, + 0x3F, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xE0, 0x7F, 0xFF, 0xC0, + 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xC0, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x01, + 0xFF, 0xFF, 0x81, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0x03, + 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x03, 0xFF, 0xFE, 0x07, 0xFF, 0xFC, 0x00, + 0x00, 0x00, 0x07, 0xFF, 0xFC, 0x0F, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x0F, + 0xFF, 0xFC, 0x1F, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xF8, 0x7F, + 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xF0, 0xFF, 0xFF, 0x80, 0x00, + 0x00, 0x00, 0x7F, 0xFF, 0xE1, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x7F, + 0xFF, 0xC3, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x87, 0xFF, + 0xF8, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0x0F, 0xFF, 0xF0, 0x00, 0x00, + 0x00, 0x03, 0xFF, 0xFF, 0x1F, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x07, 0xFF, + 0xFE, 0x3F, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFC, 0xFF, 0xFF, + 0x80, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xF9, 0xFF, 0xFF, 0x00, 0x00, 0x00, + 0x00, 0x1F, 0xFF, 0xF3, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, + 0xE7, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xCF, 0xFF, 0xF0, + 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xDF, 0xFF, 0xE0, 0x00, 0x00, 0x00, + 0x01, 0xFF, 0xFF, 0xBF, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x03, 0xFF, 0xFF, + 0x7F, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, + 0x00, 0x00, 0x00, 0x07, 0xFF, 0xFF, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x00, + 0x0F, 0xFF, 0xFF, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xFF, + 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xE0, 0x00, + 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00, + 0x7F, 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, + 0xFF, 0x00, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0xFE, 0x00, 0x00, + 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x07, + 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, + 0xE0, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0x00, + 0x00, 0x00, 0x1F, 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, 0x3F, + 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xFC, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xF8, 0x00, 0x00, 0x00, + 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x01, 0xFF, + 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xC0, + 0x00, 0x00, 0x00, 0x00, 0x07, 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00, + 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0xFF, + 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xF8, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x7F, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, + 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0x80, 0x00, + 0x00, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x07, 0xFF, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFF, + 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xF0, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0xFF, 0xFF, + 0xE0, 0x00, 0x00, 0x03, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xF7, + 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xE0, 0x00, 0x00, 0x07, 0xFF, + 0xFE, 0x7F, 0xFF, 0xE0, 0x00, 0x00, 0x03, 0xFF, 0xFE, 0x00, 0x00, 0x00, + 0x7F, 0xFF, 0xE7, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xE0, 0x00, + 0x00, 0x07, 0xFF, 0xFE, 0x7F, 0xFF, 0xE0, 0x00, 0x00, 0x03, 0xFF, 0xFF, + 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xE7, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x3F, + 0xFF, 0xF0, 0x00, 0x00, 0x07, 0xFF, 0xFE, 0x7F, 0xFF, 0xE0, 0x00, 0x00, + 0x03, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xE7, 0xFF, 0xFE, 0x00, + 0x00, 0x00, 0x7F, 0xFF, 0xF0, 0x00, 0x00, 0x07, 0xFF, 0xFE, 0x3F, 0xFF, + 0xF0, 0x00, 0x00, 0x07, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xE3, + 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xF0, 0x00, 0x00, 0x07, 0xFF, + 0xFE, 0x3F, 0xFF, 0xF0, 0x00, 0x00, 0x07, 0xFF, 0xFF, 0x00, 0x00, 0x00, + 0x7F, 0xFF, 0xC3, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xF8, 0x00, + 0x00, 0x0F, 0xFF, 0xFC, 0x3F, 0xFF, 0xF0, 0x00, 0x00, 0x07, 0xFF, 0xFF, + 0x80, 0x00, 0x00, 0xFF, 0xFF, 0xC3, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x7F, + 0xFF, 0xF8, 0x00, 0x00, 0x0F, 0xFF, 0xFC, 0x3F, 0xFF, 0xF0, 0x00, 0x00, + 0x0F, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0xFF, 0xFF, 0xC3, 0xFF, 0xFF, 0x00, + 0x00, 0x00, 0xFF, 0xFF, 0xF8, 0x00, 0x00, 0x0F, 0xFF, 0xFC, 0x1F, 0xFF, + 0xF0, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0xFF, 0xFF, 0xC1, + 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xF8, 0x00, 0x00, 0x0F, 0xFF, + 0xFC, 0x1F, 0xFF, 0xF8, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xC0, 0x00, 0x00, + 0xFF, 0xFF, 0xC1, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0xFF, 0xFF, 0xFC, 0x00, + 0x00, 0x0F, 0xFF, 0xF8, 0x1F, 0xFF, 0xF8, 0x00, 0x00, 0x0F, 0xFF, 0xFF, + 0xC0, 0x00, 0x00, 0xFF, 0xFF, 0x81, 0xFF, 0xFF, 0x80, 0x00, 0x01, 0xFF, + 0xFF, 0xFC, 0x00, 0x00, 0x1F, 0xFF, 0xF8, 0x1F, 0xFF, 0xF8, 0x00, 0x00, + 0x1F, 0xFF, 0xFF, 0xC0, 0x00, 0x01, 0xFF, 0xFF, 0x81, 0xFF, 0xFF, 0x80, + 0x00, 0x01, 0xFF, 0xFF, 0xFC, 0x00, 0x00, 0x1F, 0xFF, 0xF8, 0x0F, 0xFF, + 0xF8, 0x00, 0x00, 0x1F, 0xFF, 0xFF, 0xC0, 0x00, 0x01, 0xFF, 0xFF, 0x80, + 0xFF, 0xFF, 0x80, 0x00, 0x01, 0xFF, 0xFF, 0xFE, 0x00, 0x00, 0x1F, 0xFF, + 0xF8, 0x0F, 0xFF, 0xF8, 0x00, 0x00, 0x1F, 0xFF, 0xFF, 0xE0, 0x00, 0x01, + 0xFF, 0xFF, 0x80, 0xFF, 0xFF, 0xC0, 0x00, 0x01, 0xFF, 0xFF, 0xFE, 0x00, + 0x00, 0x1F, 0xFF, 0xF0, 0x0F, 0xFF, 0xFC, 0x00, 0x00, 0x3F, 0xFF, 0xFF, + 0xE0, 0x00, 0x01, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xC0, 0x00, 0x03, 0xFF, + 0xFF, 0xFE, 0x00, 0x00, 0x1F, 0xFF, 0xF0, 0x0F, 0xFF, 0xFC, 0x00, 0x00, + 0x3F, 0xFF, 0xFF, 0xE0, 0x00, 0x01, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xC0, + 0x00, 0x03, 0xFF, 0xFF, 0xFE, 0x00, 0x00, 0x1F, 0xFF, 0xF0, 0x07, 0xFF, + 0xFC, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xF0, 0x00, 0x03, 0xFF, 0xFF, 0x00, + 0x7F, 0xFF, 0xC0, 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x3F, 0xFF, + 0xF0, 0x07, 0xFF, 0xFC, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xF0, 0x00, 0x03, + 0xFF, 0xFF, 0x00, 0x7F, 0xFF, 0xC0, 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0x00, + 0x00, 0x3F, 0xFF, 0xF0, 0x07, 0xFF, 0xFE, 0x00, 0x00, 0x7F, 0xFF, 0xFF, + 0xF0, 0x00, 0x03, 0xFF, 0xFE, 0x00, 0x7F, 0xFF, 0xE0, 0x00, 0x07, 0xFF, + 0xFF, 0xFF, 0x00, 0x00, 0x3F, 0xFF, 0xE0, 0x07, 0xFF, 0xFE, 0x00, 0x00, + 0x7F, 0xFF, 0xFF, 0xF0, 0x00, 0x03, 0xFF, 0xFE, 0x00, 0x3F, 0xFF, 0xE0, + 0x00, 0x07, 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x3F, 0xFF, 0xE0, 0x03, 0xFF, + 0xFE, 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xF8, 0x00, 0x03, 0xFF, 0xFE, 0x00, + 0x3F, 0xFF, 0xE0, 0x00, 0x07, 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x3F, 0xFF, + 0xE0, 0x03, 0xFF, 0xFE, 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xF8, 0x00, 0x03, + 0xFF, 0xFE, 0x00, 0x3F, 0xFF, 0xE0, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0x80, + 0x00, 0x7F, 0xFF, 0xE0, 0x03, 0xFF, 0xFE, 0x00, 0x00, 0xFF, 0xFF, 0xFF, + 0xF8, 0x00, 0x07, 0xFF, 0xFC, 0x00, 0x3F, 0xFF, 0xF0, 0x00, 0x0F, 0xFF, + 0xFF, 0xFF, 0x80, 0x00, 0x7F, 0xFF, 0xC0, 0x03, 0xFF, 0xFF, 0x00, 0x00, + 0xFF, 0xFE, 0xFF, 0xFC, 0x00, 0x07, 0xFF, 0xFC, 0x00, 0x1F, 0xFF, 0xF0, + 0x00, 0x0F, 0xFF, 0xEF, 0xFF, 0xC0, 0x00, 0x7F, 0xFF, 0xC0, 0x01, 0xFF, + 0xFF, 0x00, 0x00, 0xFF, 0xFC, 0xFF, 0xFC, 0x00, 0x07, 0xFF, 0xFC, 0x00, + 0x1F, 0xFF, 0xF0, 0x00, 0x0F, 0xFF, 0xCF, 0xFF, 0xC0, 0x00, 0x7F, 0xFF, + 0xC0, 0x01, 0xFF, 0xFF, 0x00, 0x01, 0xFF, 0xFC, 0xFF, 0xFC, 0x00, 0x07, + 0xFF, 0xFC, 0x00, 0x1F, 0xFF, 0xF0, 0x00, 0x1F, 0xFF, 0xCF, 0xFF, 0xC0, + 0x00, 0x7F, 0xFF, 0xC0, 0x01, 0xFF, 0xFF, 0x00, 0x01, 0xFF, 0xFC, 0xFF, + 0xFC, 0x00, 0x07, 0xFF, 0xFC, 0x00, 0x1F, 0xFF, 0xF0, 0x00, 0x1F, 0xFF, + 0xCF, 0xFF, 0xE0, 0x00, 0xFF, 0xFF, 0x80, 0x01, 0xFF, 0xFF, 0x00, 0x01, + 0xFF, 0xFC, 0x7F, 0xFE, 0x00, 0x0F, 0xFF, 0xF8, 0x00, 0x0F, 0xFF, 0xF8, + 0x00, 0x1F, 0xFF, 0x87, 0xFF, 0xE0, 0x00, 0xFF, 0xFF, 0x80, 0x00, 0xFF, + 0xFF, 0x80, 0x01, 0xFF, 0xF8, 0x7F, 0xFE, 0x00, 0x0F, 0xFF, 0xF8, 0x00, + 0x0F, 0xFF, 0xF8, 0x00, 0x3F, 0xFF, 0x87, 0xFF, 0xE0, 0x00, 0xFF, 0xFF, + 0x80, 0x00, 0xFF, 0xFF, 0x80, 0x03, 0xFF, 0xF8, 0x7F, 0xFE, 0x00, 0x0F, + 0xFF, 0xF8, 0x00, 0x0F, 0xFF, 0xF8, 0x00, 0x3F, 0xFF, 0x87, 0xFF, 0xE0, + 0x00, 0xFF, 0xFF, 0x80, 0x00, 0xFF, 0xFF, 0x80, 0x03, 0xFF, 0xF8, 0x7F, + 0xFF, 0x00, 0x0F, 0xFF, 0xF8, 0x00, 0x0F, 0xFF, 0xF8, 0x00, 0x3F, 0xFF, + 0x83, 0xFF, 0xF0, 0x00, 0xFF, 0xFF, 0x80, 0x00, 0xFF, 0xFF, 0x80, 0x03, + 0xFF, 0xF0, 0x3F, 0xFF, 0x00, 0x0F, 0xFF, 0xF0, 0x00, 0x07, 0xFF, 0xF8, + 0x00, 0x3F, 0xFF, 0x03, 0xFF, 0xF0, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x7F, + 0xFF, 0xC0, 0x07, 0xFF, 0xF0, 0x3F, 0xFF, 0x00, 0x1F, 0xFF, 0xF0, 0x00, + 0x07, 0xFF, 0xFC, 0x00, 0x7F, 0xFF, 0x03, 0xFF, 0xF0, 0x01, 0xFF, 0xFF, + 0x00, 0x00, 0x7F, 0xFF, 0xC0, 0x07, 0xFF, 0xF0, 0x3F, 0xFF, 0x00, 0x1F, + 0xFF, 0xF0, 0x00, 0x07, 0xFF, 0xFC, 0x00, 0x7F, 0xFF, 0x03, 0xFF, 0xF8, + 0x01, 0xFF, 0xFF, 0x00, 0x00, 0x7F, 0xFF, 0xC0, 0x07, 0xFF, 0xF0, 0x1F, + 0xFF, 0x80, 0x1F, 0xFF, 0xF0, 0x00, 0x07, 0xFF, 0xFC, 0x00, 0x7F, 0xFE, + 0x01, 0xFF, 0xF8, 0x01, 0xFF, 0xFF, 0x00, 0x00, 0x7F, 0xFF, 0xC0, 0x07, + 0xFF, 0xE0, 0x1F, 0xFF, 0x80, 0x1F, 0xFF, 0xE0, 0x00, 0x03, 0xFF, 0xFC, + 0x00, 0xFF, 0xFE, 0x01, 0xFF, 0xF8, 0x01, 0xFF, 0xFE, 0x00, 0x00, 0x3F, + 0xFF, 0xC0, 0x0F, 0xFF, 0xE0, 0x1F, 0xFF, 0x80, 0x1F, 0xFF, 0xE0, 0x00, + 0x03, 0xFF, 0xFE, 0x00, 0xFF, 0xFE, 0x01, 0xFF, 0xF8, 0x01, 0xFF, 0xFE, + 0x00, 0x00, 0x3F, 0xFF, 0xE0, 0x0F, 0xFF, 0xE0, 0x1F, 0xFF, 0xC0, 0x1F, + 0xFF, 0xE0, 0x00, 0x03, 0xFF, 0xFE, 0x00, 0xFF, 0xFC, 0x00, 0xFF, 0xFC, + 0x03, 0xFF, 0xFE, 0x00, 0x00, 0x3F, 0xFF, 0xE0, 0x0F, 0xFF, 0xC0, 0x0F, + 0xFF, 0xC0, 0x3F, 0xFF, 0xE0, 0x00, 0x03, 0xFF, 0xFE, 0x00, 0xFF, 0xFC, + 0x00, 0xFF, 0xFC, 0x03, 0xFF, 0xFE, 0x00, 0x00, 0x3F, 0xFF, 0xE0, 0x1F, + 0xFF, 0xC0, 0x0F, 0xFF, 0xC0, 0x3F, 0xFF, 0xE0, 0x00, 0x01, 0xFF, 0xFE, + 0x01, 0xFF, 0xFC, 0x00, 0xFF, 0xFC, 0x03, 0xFF, 0xFC, 0x00, 0x00, 0x1F, + 0xFF, 0xE0, 0x1F, 0xFF, 0xC0, 0x0F, 0xFF, 0xC0, 0x3F, 0xFF, 0xC0, 0x00, + 0x01, 0xFF, 0xFE, 0x01, 0xFF, 0xFC, 0x00, 0xFF, 0xFE, 0x03, 0xFF, 0xFC, + 0x00, 0x00, 0x1F, 0xFF, 0xE0, 0x1F, 0xFF, 0x80, 0x07, 0xFF, 0xE0, 0x3F, + 0xFF, 0xC0, 0x00, 0x01, 0xFF, 0xFF, 0x01, 0xFF, 0xF8, 0x00, 0x7F, 0xFE, + 0x03, 0xFF, 0xFC, 0x00, 0x00, 0x1F, 0xFF, 0xF0, 0x1F, 0xFF, 0x80, 0x07, + 0xFF, 0xE0, 0x3F, 0xFF, 0xC0, 0x00, 0x01, 0xFF, 0xFF, 0x03, 0xFF, 0xF8, + 0x00, 0x7F, 0xFE, 0x03, 0xFF, 0xFC, 0x00, 0x00, 0x0F, 0xFF, 0xF0, 0x3F, + 0xFF, 0x80, 0x07, 0xFF, 0xE0, 0x7F, 0xFF, 0xC0, 0x00, 0x00, 0xFF, 0xFF, + 0x03, 0xFF, 0xF8, 0x00, 0x7F, 0xFF, 0x07, 0xFF, 0xF8, 0x00, 0x00, 0x0F, + 0xFF, 0xF0, 0x3F, 0xFF, 0x80, 0x07, 0xFF, 0xF0, 0x7F, 0xFF, 0x80, 0x00, + 0x00, 0xFF, 0xFF, 0x03, 0xFF, 0xF0, 0x00, 0x3F, 0xFF, 0x07, 0xFF, 0xF8, + 0x00, 0x00, 0x0F, 0xFF, 0xF0, 0x3F, 0xFF, 0x00, 0x03, 0xFF, 0xF0, 0x7F, + 0xFF, 0x80, 0x00, 0x00, 0xFF, 0xFF, 0x03, 0xFF, 0xF0, 0x00, 0x3F, 0xFF, + 0x07, 0xFF, 0xF8, 0x00, 0x00, 0x0F, 0xFF, 0xF8, 0x7F, 0xFF, 0x00, 0x03, + 0xFF, 0xF0, 0x7F, 0xFF, 0x80, 0x00, 0x00, 0xFF, 0xFF, 0x87, 0xFF, 0xF0, + 0x00, 0x3F, 0xFF, 0x07, 0xFF, 0xF8, 0x00, 0x00, 0x07, 0xFF, 0xF8, 0x7F, + 0xFF, 0x00, 0x03, 0xFF, 0xF8, 0x7F, 0xFF, 0x80, 0x00, 0x00, 0x7F, 0xFF, + 0x87, 0xFF, 0xF0, 0x00, 0x3F, 0xFF, 0x87, 0xFF, 0xF8, 0x00, 0x00, 0x07, + 0xFF, 0xF8, 0x7F, 0xFE, 0x00, 0x01, 0xFF, 0xF8, 0xFF, 0xFF, 0x00, 0x00, + 0x00, 0x7F, 0xFF, 0x87, 0xFF, 0xE0, 0x00, 0x1F, 0xFF, 0x8F, 0xFF, 0xF0, + 0x00, 0x00, 0x07, 0xFF, 0xF8, 0x7F, 0xFE, 0x00, 0x01, 0xFF, 0xF8, 0xFF, + 0xFF, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0x8F, 0xFF, 0xE0, 0x00, 0x1F, 0xFF, + 0x8F, 0xFF, 0xF0, 0x00, 0x00, 0x07, 0xFF, 0xF8, 0xFF, 0xFE, 0x00, 0x01, + 0xFF, 0xF8, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xCF, 0xFF, 0xE0, + 0x00, 0x1F, 0xFF, 0xCF, 0xFF, 0xF0, 0x00, 0x00, 0x03, 0xFF, 0xFC, 0xFF, + 0xFE, 0x00, 0x01, 0xFF, 0xFC, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x3F, 0xFF, + 0xCF, 0xFF, 0xC0, 0x00, 0x0F, 0xFF, 0xCF, 0xFF, 0xF0, 0x00, 0x00, 0x03, + 0xFF, 0xFC, 0xFF, 0xFC, 0x00, 0x00, 0xFF, 0xFC, 0xFF, 0xFE, 0x00, 0x00, + 0x00, 0x3F, 0xFF, 0xCF, 0xFF, 0xC0, 0x00, 0x0F, 0xFF, 0xCF, 0xFF, 0xE0, + 0x00, 0x00, 0x03, 0xFF, 0xFD, 0xFF, 0xFC, 0x00, 0x00, 0xFF, 0xFC, 0xFF, + 0xFE, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xDF, 0xFF, 0xC0, 0x00, 0x0F, 0xFF, + 0xDF, 0xFF, 0xE0, 0x00, 0x00, 0x03, 0xFF, 0xFD, 0xFF, 0xFC, 0x00, 0x00, + 0xFF, 0xFF, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xDF, 0xFF, 0x80, + 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0xFF, + 0xF8, 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x1F, 0xFF, + 0xFF, 0xFF, 0x80, 0x00, 0x07, 0xFF, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x01, + 0xFF, 0xFF, 0xFF, 0xF8, 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xFE, 0x00, 0x00, + 0x00, 0x1F, 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x07, 0xFF, 0xFF, 0xFF, 0xC0, + 0x00, 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0xF8, 0x00, 0x00, 0x7F, 0xFF, 0xFF, + 0xFC, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x07, 0xFF, + 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x00, + 0x7F, 0xFF, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xFF, 0xFF, 0x00, + 0x00, 0x07, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, + 0xF0, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x0F, 0xFF, + 0xFF, 0xFF, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x00, + 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xFC, 0x00, 0x00, + 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xC0, + 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x3F, 0xFF, 0xFF, + 0xF8, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xFE, 0x00, 0x00, 0x03, 0xFF, + 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xE0, 0x00, 0x00, + 0x3F, 0xFF, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xFE, 0x00, + 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xFF, + 0xE0, 0x00, 0x00, 0x1F, 0xFF, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x07, 0xFF, + 0xFF, 0xFE, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00, + 0x7F, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x1F, 0xFF, 0xFF, 0xF8, 0x00, 0x00, + 0x00, 0x07, 0xFF, 0xFF, 0xFE, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0x80, + 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x1F, 0xFF, 0xFF, + 0xF0, 0x00, 0x00, 0x00, 0x07, 0xFF, 0xFF, 0xFC, 0x00, 0x00, 0x01, 0xFF, + 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xC0, 0x00, 0x00, + 0x0F, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xFC, 0x00, + 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xFF, + 0xC0, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x03, 0xFF, + 0xFF, 0xFC, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, + 0x3F, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xF0, 0x00, 0x00, + 0x00, 0x03, 0xFF, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, + 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x0F, 0xFF, 0xFF, + 0xF0, 0x00, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x7F, + 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0x80, 0x00, 0x00, + 0x07, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0xF8, 0x00, + 0x00, 0x00, 0x7F, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xFF, + 0x80, 0x00, 0x00, 0x07, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x01, 0xFF, + 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x00, + 0x1F, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x07, 0xFF, 0xFF, 0xE0, 0x00, 0x00, + 0x00, 0x01, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xFE, 0x00, + 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x03, 0xFF, 0xFF, + 0xE0, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x3F, + 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xFF, 0x00, 0x00, 0x00, + 0x03, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xF0, 0x00, + 0x00, 0x00, 0x3F, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFE, + 0x00, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0xFF, 0xFF, 0xC0, + 0x00, 0x00, 0x07, 0xFF, 0xFE, 0x7F, 0xFF, 0xC0, 0x00, 0x00, 0x0F, 0xFF, + 0xFE, 0x7F, 0xFF, 0xC0, 0x00, 0x00, 0x0F, 0xFF, 0xFC, 0x7F, 0xFF, 0xE0, + 0x00, 0x00, 0x0F, 0xFF, 0xFC, 0x3F, 0xFF, 0xE0, 0x00, 0x00, 0x0F, 0xFF, + 0xFC, 0x3F, 0xFF, 0xE0, 0x00, 0x00, 0x1F, 0xFF, 0xFC, 0x3F, 0xFF, 0xF0, + 0x00, 0x00, 0x1F, 0xFF, 0xF8, 0x1F, 0xFF, 0xF0, 0x00, 0x00, 0x1F, 0xFF, + 0xF8, 0x1F, 0xFF, 0xF0, 0x00, 0x00, 0x1F, 0xFF, 0xF8, 0x1F, 0xFF, 0xF0, + 0x00, 0x00, 0x3F, 0xFF, 0xF0, 0x0F, 0xFF, 0xF8, 0x00, 0x00, 0x3F, 0xFF, + 0xF0, 0x0F, 0xFF, 0xF8, 0x00, 0x00, 0x3F, 0xFF, 0xF0, 0x0F, 0xFF, 0xF8, + 0x00, 0x00, 0x7F, 0xFF, 0xF0, 0x0F, 0xFF, 0xFC, 0x00, 0x00, 0x7F, 0xFF, + 0xE0, 0x07, 0xFF, 0xFC, 0x00, 0x00, 0x7F, 0xFF, 0xE0, 0x07, 0xFF, 0xFC, + 0x00, 0x00, 0x7F, 0xFF, 0xE0, 0x07, 0xFF, 0xFE, 0x00, 0x00, 0xFF, 0xFF, + 0xC0, 0x03, 0xFF, 0xFE, 0x00, 0x00, 0xFF, 0xFF, 0xC0, 0x03, 0xFF, 0xFE, + 0x00, 0x00, 0xFF, 0xFF, 0xC0, 0x03, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, + 0xC0, 0x01, 0xFF, 0xFF, 0x00, 0x01, 0xFF, 0xFF, 0x80, 0x01, 0xFF, 0xFF, + 0x00, 0x01, 0xFF, 0xFF, 0x80, 0x01, 0xFF, 0xFF, 0x00, 0x01, 0xFF, 0xFF, + 0x80, 0x00, 0xFF, 0xFF, 0x80, 0x01, 0xFF, 0xFF, 0x80, 0x00, 0xFF, 0xFF, + 0x80, 0x03, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x80, 0x03, 0xFF, 0xFF, + 0x00, 0x00, 0xFF, 0xFF, 0xC0, 0x03, 0xFF, 0xFF, 0x00, 0x00, 0x7F, 0xFF, + 0xC0, 0x03, 0xFF, 0xFE, 0x00, 0x00, 0x7F, 0xFF, 0xC0, 0x07, 0xFF, 0xFE, + 0x00, 0x00, 0x7F, 0xFF, 0xE0, 0x07, 0xFF, 0xFE, 0x00, 0x00, 0x3F, 0xFF, + 0xE0, 0x07, 0xFF, 0xFE, 0x00, 0x00, 0x3F, 0xFF, 0xE0, 0x0F, 0xFF, 0xFC, + 0x00, 0x00, 0x3F, 0xFF, 0xF0, 0x0F, 0xFF, 0xFC, 0x00, 0x00, 0x1F, 0xFF, + 0xF0, 0x0F, 0xFF, 0xFC, 0x00, 0x00, 0x1F, 0xFF, 0xF0, 0x0F, 0xFF, 0xF8, + 0x00, 0x00, 0x1F, 0xFF, 0xF0, 0x1F, 0xFF, 0xF8, 0x00, 0x00, 0x0F, 0xFF, + 0xF8, 0x1F, 0xFF, 0xF8, 0x00, 0x00, 0x0F, 0xFF, 0xF8, 0x1F, 0xFF, 0xF8, + 0x00, 0x00, 0x0F, 0xFF, 0xF8, 0x1F, 0xFF, 0xF0, 0x00, 0x00, 0x07, 0xFF, + 0xFC, 0x3F, 0xFF, 0xF0, 0x00, 0x00, 0x07, 0xFF, 0xFC, 0x3F, 0xFF, 0xF0, + 0x00, 0x00, 0x07, 0xFF, 0xFC, 0x3F, 0xFF, 0xE0, 0x00, 0x00, 0x07, 0xFF, + 0xFE, 0x3F, 0xFF, 0xE0, 0x00, 0x00, 0x03, 0xFF, 0xFE, 0x7F, 0xFF, 0xE0, + 0x00, 0x00, 0x03, 0xFF, 0xFE, 0x7F, 0xFF, 0xE0, 0x00, 0x00, 0x03, 0xFF, + 0xFF, 0x7F, 0xFF, 0xC0, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0x7F, 0xFF, 0xC0, + 0x00, 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x01, 0xFF, + 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, + 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00, 0xFF, + 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0x00, + 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x7F, + 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0x00, + 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x3F, + 0xFF, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xFE, 0x00, + 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x1F, + 0xFF, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xFF, 0xFC, 0x00, + 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x0F, + 0xFF, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xF8, 0x00, + 0x00, 0x00, 0x00, 0x07, 0xFF, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x07, + 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x07, 0xFF, 0xFF, 0xF0, 0x00, + 0x00, 0x00, 0x00, 0x07, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x03, + 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xE0, 0x00, + 0x00, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x07, + 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x07, 0xFF, 0xFF, 0xC0, 0x00, + 0x00, 0x00, 0x00, 0x07, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x07, + 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xC0, 0x00, + 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x0F, + 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xC0, 0x00, + 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x1F, + 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xFF, 0xE0, 0x00, + 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x3F, + 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xF0, 0x00, + 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x7F, + 0xFF, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xF8, 0x00, + 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x00, 0xFF, + 0xFF, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, + 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x00, 0xFF, + 0xFF, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0xFE, 0x00, + 0x00, 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x01, 0xFF, + 0xFF, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, + 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x03, 0xFF, + 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, + 0x00, 0x00, 0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x07, 0xFF, + 0xFE, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x07, 0xFF, 0xFE, 0xFF, 0xFF, 0xC0, + 0x00, 0x00, 0x07, 0xFF, 0xFE, 0x7F, 0xFF, 0xC0, 0x00, 0x00, 0x0F, 0xFF, + 0xFC, 0x7F, 0xFF, 0xC0, 0x00, 0x00, 0x0F, 0xFF, 0xFC, 0x7F, 0xFF, 0xE0, + 0x00, 0x00, 0x0F, 0xFF, 0xFC, 0x3F, 0xFF, 0xE0, 0x00, 0x00, 0x1F, 0xFF, + 0xFC, 0x3F, 0xFF, 0xE0, 0x00, 0x00, 0x1F, 0xFF, 0xF8, 0x3F, 0xFF, 0xF0, + 0x00, 0x00, 0x1F, 0xFF, 0xF8, 0x1F, 0xFF, 0xF0, 0x00, 0x00, 0x1F, 0xFF, + 0xF8, 0x1F, 0xFF, 0xF0, 0x00, 0x00, 0x3F, 0xFF, 0xF8, 0x1F, 0xFF, 0xF0, + 0x00, 0x00, 0x3F, 0xFF, 0xF0, 0x1F, 0xFF, 0xF8, 0x00, 0x00, 0x3F, 0xFF, + 0xF0, 0x0F, 0xFF, 0xF8, 0x00, 0x00, 0x3F, 0xFF, 0xF0, 0x0F, 0xFF, 0xF8, + 0x00, 0x00, 0x7F, 0xFF, 0xF0, 0x0F, 0xFF, 0xFC, 0x00, 0x00, 0x7F, 0xFF, + 0xE0, 0x07, 0xFF, 0xFC, 0x00, 0x00, 0x7F, 0xFF, 0xE0, 0x07, 0xFF, 0xFC, + 0x00, 0x00, 0xFF, 0xFF, 0xE0, 0x07, 0xFF, 0xFE, 0x00, 0x00, 0xFF, 0xFF, + 0xE0, 0x03, 0xFF, 0xFE, 0x00, 0x00, 0xFF, 0xFF, 0xC0, 0x03, 0xFF, 0xFE, + 0x00, 0x00, 0xFF, 0xFF, 0xC0, 0x03, 0xFF, 0xFF, 0x00, 0x01, 0xFF, 0xFF, + 0xC0, 0x01, 0xFF, 0xFF, 0x00, 0x01, 0xFF, 0xFF, 0xC0, 0x01, 0xFF, 0xFF, + 0x00, 0x01, 0xFF, 0xFF, 0x80, 0x01, 0xFF, 0xFF, 0x00, 0x03, 0xFF, 0xFF, + 0x80, 0x01, 0xFF, 0xFF, 0x80, 0x03, 0xFF, 0xFF, 0x80, 0x00, 0xFF, 0xFF, + 0x80, 0x03, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x80, 0x03, 0xFF, 0xFF, + 0x00, 0x00, 0xFF, 0xFF, 0xC0, 0x07, 0xFF, 0xFF, 0x00, 0x00, 0x7F, 0xFF, + 0xC0, 0x07, 0xFF, 0xFF, 0x00, 0x00, 0x7F, 0xFF, 0xC0, 0x07, 0xFF, 0xFE, + 0x00, 0x00, 0x7F, 0xFF, 0xE0, 0x07, 0xFF, 0xFE, 0x00, 0x00, 0x3F, 0xFF, + 0xE0, 0x0F, 0xFF, 0xFE, 0x00, 0x00, 0x3F, 0xFF, 0xE0, 0x0F, 0xFF, 0xFE, + 0x00, 0x00, 0x3F, 0xFF, 0xF0, 0x0F, 0xFF, 0xFC, 0x00, 0x00, 0x1F, 0xFF, + 0xF0, 0x1F, 0xFF, 0xFC, 0x00, 0x00, 0x1F, 0xFF, 0xF0, 0x1F, 0xFF, 0xFC, + 0x00, 0x00, 0x1F, 0xFF, 0xF8, 0x1F, 0xFF, 0xFC, 0x00, 0x00, 0x1F, 0xFF, + 0xF8, 0x1F, 0xFF, 0xF8, 0x00, 0x00, 0x0F, 0xFF, 0xF8, 0x3F, 0xFF, 0xF8, + 0x00, 0x00, 0x0F, 0xFF, 0xF8, 0x3F, 0xFF, 0xF8, 0x00, 0x00, 0x0F, 0xFF, + 0xFC, 0x3F, 0xFF, 0xF8, 0x00, 0x00, 0x07, 0xFF, 0xFC, 0x7F, 0xFF, 0xF0, + 0x00, 0x00, 0x07, 0xFF, 0xFC, 0x7F, 0xFF, 0xF0, 0x00, 0x00, 0x07, 0xFF, + 0xFE, 0x7F, 0xFF, 0xF0, 0x00, 0x00, 0x03, 0xFF, 0xFE, 0x7F, 0xFF, 0xE0, + 0x00, 0x00, 0x03, 0xFF, 0xFE, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x03, 0xFF, + 0xFF, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, + 0x00, 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x1F, + 0xFF, 0xFE, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xF9, 0xFF, + 0xFF, 0xE0, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xF1, 0xFF, 0xFF, 0xC0, 0x00, + 0x00, 0x01, 0xFF, 0xFF, 0xE3, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x03, 0xFF, + 0xFF, 0x87, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x07, 0xFF, 0xFF, 0x0F, 0xFF, + 0xFF, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xFE, 0x0F, 0xFF, 0xFE, 0x00, 0x00, + 0x00, 0x3F, 0xFF, 0xF8, 0x1F, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x7F, 0xFF, + 0xF0, 0x3F, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xE0, 0x3F, 0xFF, + 0xF8, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xC0, 0x7F, 0xFF, 0xF0, 0x00, 0x00, + 0x07, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x0F, 0xFF, 0xFE, + 0x01, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x1F, 0xFF, 0xFC, 0x01, 0xFF, 0xFF, + 0xC0, 0x00, 0x00, 0x7F, 0xFF, 0xF8, 0x03, 0xFF, 0xFF, 0x80, 0x00, 0x00, + 0xFF, 0xFF, 0xE0, 0x07, 0xFF, 0xFF, 0x80, 0x00, 0x01, 0xFF, 0xFF, 0xC0, + 0x07, 0xFF, 0xFF, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0x80, 0x0F, 0xFF, 0xFE, + 0x00, 0x00, 0x0F, 0xFF, 0xFE, 0x00, 0x1F, 0xFF, 0xFC, 0x00, 0x00, 0x1F, + 0xFF, 0xFC, 0x00, 0x3F, 0xFF, 0xFC, 0x00, 0x00, 0x3F, 0xFF, 0xF8, 0x00, + 0x3F, 0xFF, 0xF8, 0x00, 0x00, 0x7F, 0xFF, 0xF0, 0x00, 0x7F, 0xFF, 0xF0, + 0x00, 0x01, 0xFF, 0xFF, 0xC0, 0x00, 0xFF, 0xFF, 0xE0, 0x00, 0x03, 0xFF, + 0xFF, 0x80, 0x00, 0xFF, 0xFF, 0xE0, 0x00, 0x07, 0xFF, 0xFF, 0x00, 0x01, + 0xFF, 0xFF, 0xC0, 0x00, 0x0F, 0xFF, 0xFE, 0x00, 0x03, 0xFF, 0xFF, 0x80, + 0x00, 0x1F, 0xFF, 0xF8, 0x00, 0x07, 0xFF, 0xFF, 0x80, 0x00, 0x7F, 0xFF, + 0xF0, 0x00, 0x07, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xE0, 0x00, 0x0F, + 0xFF, 0xFE, 0x00, 0x01, 0xFF, 0xFF, 0x80, 0x00, 0x1F, 0xFF, 0xFC, 0x00, + 0x03, 0xFF, 0xFF, 0x00, 0x00, 0x1F, 0xFF, 0xFC, 0x00, 0x0F, 0xFF, 0xFE, + 0x00, 0x00, 0x3F, 0xFF, 0xF8, 0x00, 0x1F, 0xFF, 0xFC, 0x00, 0x00, 0x7F, + 0xFF, 0xF0, 0x00, 0x3F, 0xFF, 0xF0, 0x00, 0x00, 0x7F, 0xFF, 0xF0, 0x00, + 0x7F, 0xFF, 0xE0, 0x00, 0x00, 0xFF, 0xFF, 0xE0, 0x01, 0xFF, 0xFF, 0xC0, + 0x00, 0x01, 0xFF, 0xFF, 0xC0, 0x03, 0xFF, 0xFF, 0x80, 0x00, 0x03, 0xFF, + 0xFF, 0x80, 0x07, 0xFF, 0xFE, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0x80, 0x0F, + 0xFF, 0xFC, 0x00, 0x00, 0x07, 0xFF, 0xFF, 0x00, 0x3F, 0xFF, 0xF8, 0x00, + 0x00, 0x0F, 0xFF, 0xFE, 0x00, 0x7F, 0xFF, 0xE0, 0x00, 0x00, 0x0F, 0xFF, + 0xFC, 0x00, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x1F, 0xFF, 0xFC, 0x01, 0xFF, + 0xFF, 0x80, 0x00, 0x00, 0x3F, 0xFF, 0xF8, 0x07, 0xFF, 0xFF, 0x00, 0x00, + 0x00, 0x7F, 0xFF, 0xF0, 0x0F, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x7F, 0xFF, + 0xF0, 0x1F, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xE0, 0x3F, 0xFF, + 0xF0, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0xC0, 0xFF, 0xFF, 0xE0, 0x00, 0x00, + 0x01, 0xFF, 0xFF, 0x81, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x03, 0xFF, 0xFF, + 0x83, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x07, 0xFF, 0xFF, 0x07, 0xFF, 0xFE, + 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFE, 0x1F, 0xFF, 0xF8, 0x00, 0x00, 0x00, + 0x0F, 0xFF, 0xFE, 0x3F, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xFC, + 0x7F, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xF8, 0xFF, 0xFF, 0xC0, + 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xF1, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, + 0x7F, 0xFF, 0xF7, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xEF, + 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xDF, 0xFF, 0xF8, 0x00, + 0x00, 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x03, + 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x07, 0xFF, 0xFF, 0xFF, + 0xFF, 0x80, 0x00, 0x00, 0x00, 0x07, 0xFF, 0xFF, 0xFF, 0xFE, 0x00, 0x00, + 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x1F, + 0xFF, 0xFF, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xFF, 0xFF, + 0xF0, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0x00, + 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, 0xFF, + 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFE, + 0x00, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0xF8, 0x00, 0x00, 0x00, + 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x03, 0xFF, + 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x07, 0xFF, 0xFF, 0xFF, 0x80, + 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x1F, 0xFF, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0xFF, + 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xF0, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x7F, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, + 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0xFE, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x03, 0xFF, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xFF, 0xFF, + 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xC0, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x1F, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xFC, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xF8, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xC0, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, + 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xFC, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xFF, + 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xC0, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x07, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x0F, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0xFF, + 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xFC, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFF, + 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xC0, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x07, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x0F, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xFE, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xFC, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0xE0, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x07, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, + 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xFE, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x7F, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, + 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0xE0, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x07, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFF, + 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xFE, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x7F, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, + 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0xE0, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x07, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFF, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xFE, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x7F, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xF0, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, + 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x3F, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, + 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xF0, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x03, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xFF, + 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0x00, 0x00, + 0x00, 0x00, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF1, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF1, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF1, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF1, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xF1, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xF1, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x1F, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xF1, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x1F, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xF1, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, + 0x00, 0x01, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xFE, 0x00, + 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xFE, + 0x00, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x3F, 0xFF, + 0xFC, 0x00, 0x00, 0x00, 0x07, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x7F, + 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x07, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00, + 0x7F, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0x80, 0x00, 0x00, + 0x00, 0xFF, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0x00, 0x00, + 0x00, 0x01, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xFF, 0x00, + 0x00, 0x00, 0x01, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xFE, + 0x00, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x3F, 0xFF, + 0xFE, 0x00, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x3F, + 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x07, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x00, + 0x7F, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x07, 0xFF, 0xFF, 0x80, 0x00, 0x00, + 0x00, 0x7F, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0x80, 0x00, + 0x00, 0x00, 0xFF, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0x00, + 0x00, 0x00, 0x01, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xFF, + 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x1F, 0xFF, + 0xFE, 0x00, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x3F, + 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x00, + 0x3F, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x07, 0xFF, 0xFF, 0xC0, 0x00, 0x00, + 0x00, 0x7F, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x07, 0xFF, 0xFF, 0x80, 0x00, + 0x00, 0x00, 0x7F, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0x80, + 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFF, + 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x1F, 0xFF, + 0xFF, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x1F, + 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x00, + 0x3F, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xE0, 0x00, 0x00, + 0x00, 0x3F, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x07, 0xFF, 0xFF, 0xC0, 0x00, + 0x00, 0x00, 0x7F, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x07, 0xFF, 0xFF, 0xC0, + 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFF, + 0x80, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x0F, 0xFF, + 0xFF, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x1F, + 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, + 0x1F, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xE0, 0x00, 0x00, + 0x00, 0x3F, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xE0, 0x00, + 0x00, 0x00, 0x3F, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x07, 0xFF, 0xFF, 0xC0, + 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x07, 0xFF, 0xFF, + 0xC0, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x0F, 0xFF, + 0xFF, 0x80, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x0F, + 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, + 0x1F, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0xF0, 0x00, 0x00, + 0x00, 0x1F, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xE0, 0x00, + 0x00, 0x00, 0x3F, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xE0, + 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x07, 0xFF, 0xFF, + 0xC0, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x07, 0xFF, + 0xFF, 0xC0, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x0F, + 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xF8, 0x00, 0x00, 0x00, + 0x0F, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0xF0, 0x00, 0x00, + 0x00, 0x1F, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0xF0, 0x00, + 0x00, 0x00, 0x1F, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xE0, + 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x03, 0xFF, 0xFF, + 0xE0, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x07, 0xFF, + 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x07, + 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xF8, 0x00, 0x00, 0x00, + 0x0F, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xF8, 0x00, 0x00, + 0x00, 0x0F, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0xF0, 0x00, + 0x00, 0x00, 0x1F, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0xF0, + 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x03, 0xFF, 0xFF, + 0xE0, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x03, 0xFF, + 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x07, + 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xFC, 0x00, 0x00, 0x00, + 0x07, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xF8, 0x00, 0x00, + 0x00, 0x0F, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xF8, 0x00, + 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xEF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xEF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xEF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xEF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xEF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xEF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xEF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xEF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, + 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x3F, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xFF, + 0xC0, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0x00, + 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x1F, 0xFF, + 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0x00, 0x00, 0x00, 0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x00, 0x00, 0x00, + 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, + 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0x01, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFE, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x00, + 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x07, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0x3F, 0xFF, 0xFF, 0xE0, 0x7F, 0xFF, + 0xFF, 0x80, 0x00, 0xFF, 0xFF, 0xFE, 0x00, 0x7F, 0xFF, 0xFE, 0x00, 0x07, + 0xFF, 0xFF, 0xE0, 0x00, 0xFF, 0xFF, 0xF8, 0x00, 0x1F, 0xFF, 0xFF, 0x00, + 0x01, 0xFF, 0xFF, 0xF0, 0x00, 0x7F, 0xFF, 0xFC, 0x00, 0x03, 0xFF, 0xFF, + 0xC0, 0x01, 0xFF, 0xFF, 0xE0, 0x00, 0x0F, 0xFF, 0xFF, 0x00, 0x0F, 0xFF, + 0xFF, 0x80, 0x00, 0x1F, 0xFF, 0xFC, 0x00, 0x3F, 0xFF, 0xFC, 0x00, 0x00, + 0x7F, 0xFF, 0xF0, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x01, 0xFF, 0xFF, 0xE0, + 0x03, 0xFF, 0xFF, 0xC0, 0x00, 0x07, 0xFF, 0xFF, 0x80, 0x0F, 0xFF, 0xFF, + 0x00, 0x00, 0x1F, 0xFF, 0xFE, 0x00, 0x7F, 0xFF, 0xF8, 0x00, 0x00, 0x3F, + 0xFF, 0xF8, 0x01, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0xFF, 0xFF, 0xE0, 0x07, + 0xFF, 0xFF, 0x80, 0x00, 0x03, 0xFF, 0xFF, 0x80, 0x1F, 0xFF, 0xFE, 0x00, + 0x00, 0x0F, 0xFF, 0xFE, 0x00, 0x7F, 0xFF, 0xF8, 0x00, 0x00, 0x3F, 0xFF, + 0xFC, 0x01, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0xFF, 0xFF, 0xF0, 0x07, 0xFF, + 0xFF, 0x80, 0x00, 0x03, 0xFF, 0xFF, 0xC0, 0x1F, 0xFF, 0xFE, 0x00, 0x00, + 0x0F, 0xFF, 0xFF, 0x00, 0x7F, 0xFF, 0xF0, 0x00, 0x00, 0x3F, 0xFF, 0xFC, + 0x03, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0xFF, 0xFF, 0xF0, 0x0F, 0xFF, 0xFF, + 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xC0, 0x3F, 0xFF, 0xFC, 0x00, 0x00, 0x0F, + 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x3F, 0xFF, 0xFC, 0x03, + 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0xFF, 0xFF, 0xF0, 0x0F, 0xFF, 0xFF, 0x00, + 0x00, 0x03, 0xFF, 0xFF, 0xC0, 0x3F, 0xFF, 0xFC, 0x00, 0x00, 0x0F, 0xFF, + 0xFF, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x3F, 0xFF, 0xFC, 0x03, 0xFF, + 0xFF, 0xC0, 0x00, 0x00, 0xFF, 0xFF, 0xF0, 0x0F, 0xFF, 0xFF, 0x00, 0x00, + 0x03, 0xFF, 0xFF, 0xC0, 0x3F, 0xFF, 0xFC, 0x00, 0x00, 0x0F, 0xFF, 0xFF, + 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x3F, 0xFF, 0xFC, 0x03, 0xFF, 0xFF, + 0xC0, 0x00, 0x00, 0xFF, 0xFF, 0xF0, 0x0F, 0xFF, 0xFF, 0x00, 0x00, 0x03, + 0xFF, 0xFF, 0xC0, 0x3F, 0xFF, 0xFC, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0x00, + 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x3F, 0xFF, 0xFC, 0x03, 0xFF, 0xFF, 0xC0, + 0x00, 0x00, 0xFF, 0xFF, 0xF0, 0x0F, 0xFF, 0xFF, 0x00, 0x00, 0x03, 0xFF, + 0xFF, 0xC0, 0x3F, 0xFF, 0xFC, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0x00, 0xFF, + 0xFF, 0xF0, 0x00, 0x00, 0x3F, 0xFF, 0xFC, 0x03, 0xFF, 0xFF, 0xC0, 0x00, + 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x03, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, + 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x3F, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xF0, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, + 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x3F, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xF0, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0x00, + 0x00, 0x0F, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, + 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x0F, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xFC, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFC, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x00, + 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x0F, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, + 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x03, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, + 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x03, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xFC, 0x00, 0x00, 0x0F, 0xFF, + 0xFF, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x3F, 0xFF, 0xFC, 0x03, 0xFF, + 0xFF, 0xC0, 0x00, 0x00, 0xFF, 0xFF, 0xF0, 0x0F, 0xFF, 0xFF, 0x00, 0x00, + 0x03, 0xFF, 0xFF, 0xC0, 0x3F, 0xFF, 0xFC, 0x00, 0x00, 0x0F, 0xFF, 0xFF, + 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x3F, 0xFF, 0xFC, 0x03, 0xFF, 0xFF, + 0xC0, 0x00, 0x00, 0xFF, 0xFF, 0xF0, 0x0F, 0xFF, 0xFF, 0x00, 0x00, 0x03, + 0xFF, 0xFF, 0xC0, 0x3F, 0xFF, 0xFC, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0x00, + 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x3F, 0xFF, 0xFC, 0x03, 0xFF, 0xFF, 0xC0, + 0x00, 0x00, 0xFF, 0xFF, 0xF0, 0x0F, 0xFF, 0xFF, 0x00, 0x00, 0x03, 0xFF, + 0xFF, 0xC0, 0x3F, 0xFF, 0xFC, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0x00, 0xFF, + 0xFF, 0xF0, 0x00, 0x00, 0x3F, 0xFF, 0xFC, 0x03, 0xFF, 0xFF, 0xC0, 0x00, + 0x00, 0xFF, 0xFF, 0xF0, 0x0F, 0xFF, 0xFF, 0x00, 0x00, 0x03, 0xFF, 0xFF, + 0xC0, 0x3F, 0xFF, 0xFC, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, + 0xF0, 0x00, 0x00, 0x3F, 0xFF, 0xFC, 0x03, 0xFF, 0xFF, 0xC0, 0x00, 0x00, + 0xFF, 0xFF, 0xF0, 0x0F, 0xFF, 0xFF, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xC0, + 0x3F, 0xFF, 0xFC, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xF0, + 0x00, 0x00, 0x3F, 0xFF, 0xFC, 0x03, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0xFF, + 0xFF, 0xF0, 0x0F, 0xFF, 0xFF, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xC0, 0x3F, + 0xFF, 0xFC, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xF0, 0x00, + 0x00, 0x3F, 0xFF, 0xFC, 0x03, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0xFF, 0xFF, + 0xF0, 0x07, 0xFF, 0xFF, 0x80, 0x00, 0x03, 0xFF, 0xFF, 0xC0, 0x1F, 0xFF, + 0xFE, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0x00, 0x7F, 0xFF, 0xF8, 0x00, 0x00, + 0x3F, 0xFF, 0xFC, 0x01, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0xFF, 0xFF, 0xF0, + 0x07, 0xFF, 0xFF, 0x80, 0x00, 0x03, 0xFF, 0xFF, 0xC0, 0x1F, 0xFF, 0xFE, + 0x00, 0x00, 0x0F, 0xFF, 0xFE, 0x00, 0x7F, 0xFF, 0xF8, 0x00, 0x00, 0x3F, + 0xFF, 0xF8, 0x01, 0xFF, 0xFF, 0xE0, 0x00, 0x01, 0xFF, 0xFF, 0xE0, 0x03, + 0xFF, 0xFF, 0x80, 0x00, 0x07, 0xFF, 0xFF, 0x80, 0x0F, 0xFF, 0xFF, 0x00, + 0x00, 0x1F, 0xFF, 0xFE, 0x00, 0x3F, 0xFF, 0xFC, 0x00, 0x00, 0x7F, 0xFF, + 0xF8, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x01, 0xFF, 0xFF, 0xE0, 0x03, 0xFF, + 0xFF, 0xC0, 0x00, 0x0F, 0xFF, 0xFF, 0x00, 0x07, 0xFF, 0xFF, 0x80, 0x00, + 0x3F, 0xFF, 0xFC, 0x00, 0x1F, 0xFF, 0xFE, 0x00, 0x00, 0xFF, 0xFF, 0xF0, + 0x00, 0x7F, 0xFF, 0xFC, 0x00, 0x07, 0xFF, 0xFF, 0xC0, 0x00, 0xFF, 0xFF, + 0xF0, 0x00, 0x1F, 0xFF, 0xFE, 0x00, 0x03, 0xFF, 0xFF, 0xE0, 0x00, 0xFF, + 0xFF, 0xF8, 0x00, 0x0F, 0xFF, 0xFF, 0xE0, 0x0F, 0xFF, 0xFF, 0xE0, 0x00, + 0x1F, 0xFF, 0xFF, 0xE1, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x7F, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xE0, 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x07, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x00, 0x00, 0x1F, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, + 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x00, 0x00, 0x01, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0x80, 0x00, 0x00, 0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x00, + 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x1F, 0xFF, + 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xFF, 0xFF, 0xF8, + 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00, + 0x00, 0x1F, 0xFF, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0xFF, + 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xFF, 0x80, 0x00, 0x00, + 0x00}; const GFXglyph Antonio_SemiBold90pt7bGlyphs[] PROGMEM = { {0, 1, 1, 38, 0, 0}, // 0x20 ' ' @@ -1078,24 +5090,11 @@ const GFXglyph Antonio_SemiBold90pt7bGlyphs[] PROGMEM = { {53398, 108, 151, 116, 4, 106}, // 0x57 'W' {55437, 64, 151, 72, 4, 106}, // 0x58 'X' {56645, 71, 151, 73, 1, 106}, // 0x59 'Y' - {57986, 52, 151, 61, 6, 106}, // 0x5A 'Z' - {58968, 70, 155, 84, 5, 104}, // Euro-sign as [ - {0, 0, 0, 0, 0, 0}, // Skip backslash - {60325, 67, 153, 82, 7, 104 }, // Pound-sign as ] - {61607, 71, 151, 73, 1, 106 }, // Yen-sign as ^ + {57986, 52, 151, 61, 6, 106}, + {58968, 70, 155, 84, 5, 104}}; // 0x5A 'Z' - }; +const GFXfont Antonio_SemiBold90pt7b PROGMEM = { + (uint8_t *)Antonio_SemiBold90pt7bBitmaps, + (GFXglyph *)Antonio_SemiBold90pt7bGlyphs, 0x20, 0x5B, 228}; - - - -// Font properties -static constexpr FontData Antonio_SemiBold90pt7b_Properties = { - Antonio_SemiBold90pt7bBitmaps_Gzip, - Antonio_SemiBold90pt7bGlyphs, - sizeof(Antonio_SemiBold90pt7bBitmaps_Gzip), - 62948, // Original size - 0x20, // First char - 0x5E, // Last char - 231 // yAdvance -}; \ No newline at end of file +// Approx. 60745 bytes diff --git a/src/fonts/fonts.hpp b/src/fonts/fonts.hpp index 8f66032..1504d45 100644 --- a/src/fonts/fonts.hpp +++ b/src/fonts/fonts.hpp @@ -1,97 +1,14 @@ #pragma once -#include -#include -#include +#include "antonio-semibold20.h" +#include "antonio-semibold30.h" +#include "antonio-semibold40.h" +#include "antonio-semibold90.h" +#include "sats-symbol.h" -// Font metadata structure -struct FontData { - const uint8_t* compressedData; - const GFXglyph* glyphs; - const size_t compressedSize; - const size_t originalSize; - const uint16_t first; - const uint16_t last; - const uint8_t yAdvance; -}; - -// Font name constants -namespace FontNames { - static const String ANTONIO = "antonio"; - static const String OSWALD = "oswald"; - - static const std::array AVAILABLE_FONTS = { - ANTONIO, - OSWALD - }; - - static const std::array& getAvailableFonts() { - return AVAILABLE_FONTS; - } -} - -class FontLoader { -public: - static GFXfont* loadCompressedFont(const FontData& fontData) { - return loadCompressedFont( - fontData.compressedData, - fontData.glyphs, - fontData.compressedSize, - fontData.originalSize, - fontData.first, - fontData.last, - fontData.yAdvance - ); - } - - static GFXfont* loadCompressedFont( - const uint8_t* compressedData, - const GFXglyph* glyphs, - const size_t compressedSize, - const size_t originalSize, - const uint16_t first, - const uint16_t last, - const uint8_t yAdvance) - { - uint8_t* decompressedData = (uint8_t*)malloc(originalSize); - if (!decompressedData) { - Serial.println(F("Failed to allocate memory for font decompression")); - return nullptr; - } - - size_t decompressedSize = originalSize; - if (GzipDecompressor::decompressData(compressedData, - compressedSize, - decompressedData, - &decompressedSize)) - { - GFXfont* font = (GFXfont*)malloc(sizeof(GFXfont)); - if (!font) { - free(decompressedData); - Serial.println(F("Failed to allocate memory for font structure")); - return nullptr; - } - - font->bitmap = decompressedData; - font->glyph = (GFXglyph*)glyphs; - font->first = first; - font->last = last; - font->yAdvance = yAdvance; - - return font; - } - - Serial.println(F("Font decompression failed")); - free(decompressedData); - return nullptr; - } - - static void unloadFont(GFXfont* font) { - if (font) { - if (font->bitmap) { - free((void*)font->bitmap); - } - free(font); - } - } -}; +// #include "oswald-20.h" +// #include "oswald-30.h" +// #include "oswald-90.h" +// #include "ubuntu-italic40.h" +// #include "ubuntu-italic60.h" +// #include "ubuntu-italic70.h" \ No newline at end of file diff --git a/src/fonts/oswald-medium20.h b/src/fonts/oswald-medium20.h deleted file mode 100644 index 0509361..0000000 --- a/src/fonts/oswald-medium20.h +++ /dev/null @@ -1,323 +0,0 @@ -#pragma once - -#include -#include -#include "fonts.hpp" - -const uint8_t Oswald_Medium20pt7bBitmaps_Gzip[] = { - 0x1f,0x8b,0x08,0x00,0xf7,0xa4,0x71,0x67,0x02,0xff,0xad,0x58, - 0xcf,0x8e,0xdb,0xb8,0x19,0xa7,0xa0,0xa2,0xbc,0x04,0xe1,0xb5, - 0x87,0x81,0x98,0x37,0xe8,0x1e,0xb3,0x80,0x22,0xf6,0x51,0xda, - 0x37,0x48,0xb1,0x87,0x3a,0x18,0x45,0xd4,0xc0,0x07,0xdf,0x56, - 0x2f,0xb0,0x88,0x5f,0x63,0x81,0xa6,0x19,0x1a,0x2e,0xe0,0x4b, - 0xb1,0x7e,0x81,0x36,0xa6,0xa1,0x83,0x6f,0x2b,0x1a,0x3e,0x98, - 0x86,0x39,0x64,0x7f,0x94,0xec,0x19,0x4f,0x32,0x49,0x16,0x45, - 0xc5,0xb1,0xf4,0xf1,0xff,0xc7,0xef,0xef,0x8f,0x43,0x42,0x7c, - 0x8e,0xff,0xde,0x7c,0xff,0xcb,0x0f,0x3f,0x6d,0xbe,0xff,0xd7, - 0x8b,0x24,0x56,0xbd,0x5c,0xbe,0xe9,0x5e,0x6d,0x7e,0xde,0x67, - 0xed,0x4f,0x3f,0xfc,0x48,0x58,0x43,0x27,0xe3,0xc5,0xac,0x55, - 0x5b,0x3d,0x32,0xf9,0xa8,0xc8,0xb3,0x8c,0x31,0xd1,0xcf,0x34, - 0x5b,0x6d,0xcd,0x68,0x94,0xe7,0x32,0xdc,0x86,0x55,0xe8,0xc2, - 0xae,0x9d,0xad,0xb5,0x31,0x23,0x9b,0x8f,0xb2,0x9c,0x65,0xb4, - 0xa1,0x8b,0xf1,0x7c,0xd6,0x6a,0x52,0x93,0x3f,0x91,0x17,0xc4, - 0x27,0x61,0x16,0xb6,0xc1,0xba,0xca,0xf1,0x8a,0xdd,0xd2,0xd5, - 0xb8,0x53,0xa9,0x49,0x1c,0x09,0x44,0x28,0x66,0xd2,0x33,0x81, - 0x96,0x8a,0x88,0x9c,0x79,0x1a,0xc6,0x61,0x76,0xd4,0x77,0xd6, - 0x49,0x2f,0x3c,0x0b,0xa9,0x27,0x7f,0x20,0xcf,0xc8,0xef,0x49, - 0x4a,0x58,0x9d,0x11,0x66,0x69,0x4d,0x43,0xa2,0xd2,0xa0,0x5f, - 0x13,0x6b,0x73,0x92,0x17,0x8c,0x30,0x3a,0xae,0x53,0xb0,0x41, - 0xc0,0x19,0xc9,0xb3,0x2b,0x34,0x34,0x24,0x05,0xff,0xc4,0x58, - 0x4d,0x8a,0xe2,0x25,0x61,0x21,0x23,0x49,0x58,0x4c,0xac,0x58, - 0xcf,0x43,0xaa,0xb6,0x41,0x93,0x7c,0x64,0xc9,0xf3,0x22,0x23, - 0x69,0x33,0x51,0x49,0xbb,0x36,0x64,0x64,0x4b,0x72,0x55,0x70, - 0xc2,0xd8,0x44,0xa5,0x73,0x34,0x68,0x3b,0x22,0x23,0x8c,0xc8, - 0x68,0xa8,0xe9,0x4d,0x50,0x89,0x12,0x86,0x18,0x6a,0xa8,0x4e, - 0x03,0x09,0x86,0x7b,0xda,0x6a,0x5b,0x72,0x36,0x5e,0x9b,0xb2, - 0x60,0x93,0x7a,0x6b,0x78,0x9e,0x74,0x44,0xe8,0xd4,0xe2,0x30, - 0xac,0x4e,0x6d,0x1e,0x26,0x1f,0xb6,0xfb,0x95,0xd8,0x6e,0x3e, - 0x14,0xfb,0xb9,0xb7,0x72,0x4a,0x77,0xba,0x2c,0xf9,0x26,0xf8, - 0x10,0x96,0xce,0x06,0x06,0x91,0xfe,0xfa,0xab,0xa6,0x8c,0x8b, - 0xaa,0x2c,0xed,0x97,0x9e,0xb2,0x2c,0x85,0xe0,0x54,0x97,0x82, - 0xcf,0x35,0x36,0xc3,0x9e,0x33,0x63,0xe3,0x77,0x02,0x46,0xef, - 0x89,0x81,0x62,0xcd,0x72,0x31,0x57,0xac,0x7e,0x99,0xa8,0x1f, - 0xff,0xf8,0x37,0x6c,0xd0,0x5a,0x56,0x7b,0x36,0x3a,0xb6,0x3f, - 0x3e,0xfb,0x73,0x5a,0x53,0xf2,0x9c,0x5c,0x91,0x97,0xe4,0x75, - 0xaf,0x50,0x7f,0x5f,0x25,0x3a,0x51,0x68,0xf8,0xe9,0xd7,0x3d, - 0xc1,0xc7,0xe1,0x57,0x93,0x51,0xaa,0xae,0x88,0x66,0xf8,0xd6, - 0x79,0xa2,0x9f,0x93,0xd7,0x14,0x5f,0x95,0x41,0x08,0xe4,0x65, - 0x8a,0xef,0xd0,0x75,0x95,0xe0,0x7b,0xee,0xa2,0x86,0x41,0x6b, - 0x4d,0x58,0x84,0xdd,0xfa,0x68,0xde,0x5a,0xe1,0x38,0xea,0xbd, - 0x56,0x83,0x0e,0x46,0x7e,0xa1,0x61,0x45,0x97,0x8b,0x0d,0x0c, - 0xc5,0x48,0xc3,0x4d,0x3a,0xdb,0xde,0x45,0xe6,0x2a,0x4e,0x67, - 0xa6,0xfc,0xca,0xcb,0x70,0x27,0xbc,0xf4,0x52,0x3a,0x61,0xf9, - 0xa9,0x08,0x22,0x48,0x01,0xf9,0x3b,0xe2,0x12,0x9b,0x9a,0x14, - 0xea,0xa2,0x8a,0x29,0x5e,0xf3,0x5a,0xa0,0x39,0x76,0x40,0xfa, - 0x7d,0x61,0x46,0x58,0x09,0x3b,0x73,0x95,0x15,0xf6,0xb4,0x02, - 0x89,0xf3,0xab,0xd4,0xa5,0x16,0xc5,0xc1,0xfa,0xaa,0xbe,0xe5, - 0x7e,0x75,0xb0,0x5b,0x05,0x8f,0x0d,0x1d,0x37,0xc4,0x13,0x51, - 0x33,0x4d,0x6d,0xe2,0x49,0xa8,0x85,0xce,0x2c,0xfd,0x90,0x74, - 0xf5,0x4e,0xe7,0x36,0x2b,0x68,0x33,0x6e,0xb5,0xb1,0x79,0xd4, - 0x0d,0x28,0x1b,0xce,0x0f,0xb8,0x83,0x6d,0x68,0x62,0xef,0x89, - 0x33,0x3f,0xc1,0x5b,0xf2,0x50,0x0e,0x26,0x58,0xe8,0xe1,0xc4, - 0x1d,0xe1,0xe7,0x72,0xe6,0xc4,0x15,0xd2,0xf7,0x07,0x37,0x83, - 0xcc,0x27,0x61,0xd1,0xee,0xf4,0x01,0x32,0x2f,0x7a,0x67,0x22, - 0xbc,0x66,0xff,0xa4,0xa1,0x0d,0x87,0x68,0x6d,0x15,0x8f,0xce, - 0xf7,0x48,0xe6,0xd3,0x5e,0xe6,0xeb,0x41,0xe6,0x67,0xe6,0x5c, - 0xaa,0x59,0x5d,0x24,0x96,0x2a,0x4e,0xca,0xc4,0x30,0x55,0x10, - 0x9b,0x6a,0x5e,0x83,0xa6,0x4a,0x44,0xfa,0xa1,0x3b,0x35,0xac, - 0x66,0x26,0xb2,0x22,0x7d,0x55,0xb9,0xe2,0x2c,0x43,0x27,0xca, - 0xa2,0xac,0xb0,0x87,0x1d,0xfa,0xca,0xe2,0x42,0x3f,0xa7,0x11, - 0xe0,0xdd,0x0b,0xc7,0xa0,0x9d,0xd3,0x98,0xca,0xdd,0xeb,0xe0, - 0x61,0x14,0x54,0x1b,0x64,0x10,0x2b,0x36,0xbd,0x38,0xbd,0xb8, - 0x3c,0x7b,0xb4,0x55,0x12,0x9f,0x34,0x46,0xa7,0xfb,0x1a,0x21, - 0xd1,0xbc,0xaf,0xfe,0xfa,0xee,0x35,0x79,0xf1,0x8c,0x8e,0xb7, - 0x90,0xc0,0x42,0x1b,0x9e,0x3a,0xd1,0x7a,0xae,0x2c,0x25,0x2f, - 0x86,0xf3,0x9a,0x61,0x70,0xef,0x0a,0xf5,0x33,0x82,0xf3,0x06, - 0x0a,0xcd,0x4a,0x62,0x04,0xdb,0xf9,0xd0,0x68,0xfb,0x1c,0x91, - 0x8c,0x69,0xb9,0x0d,0x7b,0x44,0xbb,0x00,0x41,0xe3,0x58,0x42, - 0x95,0xc4,0x26,0x91,0x77,0xd8,0x94,0x83,0x18,0x20,0x99,0x92, - 0x98,0x44,0xa7,0x8a,0xd6,0xc3,0x8a,0xbd,0xf1,0x51,0xcd,0x14, - 0x41,0x68,0x43,0xfc,0x51,0x84,0x07,0x8b,0x1f,0x4c,0x06,0xb6, - 0x28,0xa0,0x77,0x4e,0x08,0xcc,0x8d,0xe4,0x3c,0xd9,0x34,0x2c, - 0x39,0x2e,0x9a,0x71,0x68,0x17,0x37,0xc1,0xec,0x67,0xd6,0x5c, - 0xcf,0xec,0xe8,0x95,0xb6,0x79,0x66,0x6c,0xc1,0x46,0xb0,0x74, - 0x57,0xb0,0xb1,0xcf,0xe8,0xcc,0xb3,0x54,0x75,0xf4,0x46,0xef, - 0xc7,0xca,0x5c,0xc3,0xf5,0xdf,0x18,0xeb,0x72,0x2b,0x7d,0x9e, - 0xf3,0xce,0x65,0x74,0xef,0xd8,0x8d,0xb1,0xa9,0x22,0x24,0x89, - 0x27,0x2b,0xa3,0x1c,0xf0,0x63,0x08,0xc7,0x69,0x98,0x2a,0x9c, - 0x53,0x83,0x07,0x83,0x58,0xa8,0x48,0x6a,0x88,0x44,0x0f,0x42, - 0xb0,0x84,0x16,0x13,0xc4,0x61,0xcd,0x5c,0xb2,0xaf,0x0b,0x43, - 0x57,0xe4,0xa8,0x8b,0x92,0x2e,0x6b,0x6b,0x38,0x4f,0x5b,0xed, - 0x86,0x28,0x27,0x11,0xaf,0xda,0xe0,0x64,0x68,0x6e,0xb6,0x46, - 0x14,0x69,0xa7,0xde,0x5a,0x76,0x9b,0xec,0x95,0x08,0x5a,0xa0, - 0x6f,0x17,0x9c,0x93,0xb7,0x68,0x3e,0x9a,0xc2,0x21,0x74,0x0f, - 0x04,0xbf,0x0d,0xcb,0x30,0x87,0x2d,0x07,0xc1,0x3a,0x15,0x8c, - 0x70,0x08,0xe0,0x41,0xc1,0xe8,0x06,0x02,0xf6,0x17,0x42,0x1c, - 0xd3,0x06,0xb8,0x52,0x0c,0x0c,0xdb,0xe0,0x2a,0x3e,0xa5,0xa7, - 0x75,0x6e,0xd3,0xd0,0xcf,0xc2,0x49,0x18,0x72,0x07,0x79,0x20, - 0xb0,0x45,0xec,0xea,0xc7,0x74,0xea,0x60,0xab,0xc8,0x20,0x2c, - 0x5c,0x98,0x4b,0x7e,0xe8,0xb0,0xe9,0x69,0xf0,0x37,0x89,0xd9, - 0xd1,0xc0,0x58,0xc4,0xc0,0xcf,0xc9,0x2b,0x4e,0x2a,0xbe,0xff, - 0xa0,0x53,0x38,0x2c,0xbf,0xbc,0x6c,0xec,0x3f,0xe1,0xd1,0xa3, - 0xaa,0xd4,0xf0,0xda,0x51,0x2d,0x12,0xcb,0x50,0x09,0x2b,0x0f, - 0x33,0xba,0x1d,0x2a,0x8f,0x7a,0x50,0x39,0x9f,0xdd,0xe3,0xec, - 0xe9,0x23,0x9e,0x2f,0x8e,0x2c,0x03,0x47,0x68,0x85,0x80,0x2e, - 0x64,0x88,0x31,0x77,0x16,0x8e,0xb2,0xf4,0xdb,0xf0,0x5e,0x2c, - 0x3f,0x11,0xef,0x67,0xc4,0x03,0x77,0x5f,0x1e,0x13,0x89,0xf0, - 0xc4,0xf3,0x8d,0x78,0x3c,0x33,0x4e,0x60,0xde,0xd1,0x21,0xf8, - 0xb2,0xd5,0xcd,0xce,0x54,0x15,0x5b,0xce,0xb6,0xb6,0x12,0x6c, - 0xd2,0x1a,0x58,0xd1,0x74,0x8c,0xb6,0xd8,0x05,0x05,0x61,0xa3, - 0x3a,0x58,0x1e,0xd2,0xa3,0xc6,0xb0,0xc5,0xcc,0x62,0xee,0x64, - 0x1d,0x57,0xc0,0xd8,0x38,0x11,0x1a,0xe5,0xb7,0xe9,0x1e,0x23, - 0x3f,0x11,0xff,0x37,0x3f,0x27,0x6e,0x2b,0x72,0x67,0x31,0x9f, - 0xad,0x94,0x94,0xc9,0x9d,0xa3,0x7b,0xc3,0x57,0x2a,0xc8,0xf1, - 0x9d,0x67,0x7b,0x2b,0x56,0xba,0xbb,0x9e,0xfc,0xa3,0xcb,0xf6, - 0xef,0xaf,0x3f,0x6e,0xbb,0xeb,0xc5,0xab,0x4d,0xbe,0x7f,0xb7, - 0xfb,0x78,0xbd,0x3c,0x74,0x62,0xf3,0x73,0x68,0x5a,0x2f,0x1a, - 0xeb,0x45,0x6b,0xc3,0x64,0xee,0x39,0xb3,0xa5,0x58,0x9b,0x30, - 0x19,0xfb,0xe7,0xcc,0x32,0x47,0x7d,0x1a,0x6e,0x7a,0xdb,0xb5, - 0xc2,0xf3,0x10,0xa3,0x6f,0x1b,0xd5,0x12,0x3e,0xca,0x4e,0xec, - 0x57,0x87,0x0e,0x81,0x5b,0x40,0x57,0x0d,0x2c,0x7f,0x7d,0x8e, - 0xb8,0x51,0x55,0x35,0x64,0x0b,0x03,0x65,0x17,0xda,0xbe,0xfd, - 0x6d,0x86,0xf9,0x40,0xdc,0x45,0x4b,0x6f,0x4e,0x96,0x6e,0x04, - 0xc8,0x1d,0xd2,0x84,0xb8,0x4d,0x3f,0xb5,0xf4,0x5b,0xd6,0x85, - 0x63,0xcc,0x21,0xa0,0x1f,0xbb,0xce,0x67,0xc4,0xff,0x8b,0x9f, - 0x98,0xd4,0x54,0x12,0x73,0x1b,0x25,0x44,0x45,0x3f,0xbc,0xe7, - 0x2e,0x3c,0x38,0xff,0x30,0xf5,0xc4,0x1d,0x34,0xce,0x16,0xed, - 0xd6,0xba,0x42,0xb0,0xe5,0x7c,0x67,0x9c,0xe3,0x82,0x76,0xf0, - 0xc3,0xea,0xec,0xfc,0x9c,0xe9,0x21,0x53,0xfb,0xca,0x9e,0xb2, - 0x0c,0x2c,0x0c,0xe9,0x57,0x22,0x76,0x09,0x8d,0x0c,0x88,0x5c, - 0x9d,0x0c,0x0d,0x62,0x74,0x9f,0x85,0xbc,0x88,0x18,0x32,0x66, - 0x99,0x7b,0x03,0xd6,0x08,0xdb,0x69,0x04,0x04,0x35,0x07,0x8b, - 0x7d,0x14,0xff,0x56,0xf5,0xb7,0xcb,0xe1,0x53,0x62,0xff,0x48, - 0x32,0x96,0x02,0x0c,0xd7,0x6f,0x0d,0x2f,0xd9,0x2a,0xdd,0xa8, - 0x83,0x29,0x0a,0xd6,0x4c,0xda,0x01,0xbf,0xd1,0xc9,0x6c,0xab, - 0x4b,0xcb,0x0b,0x04,0xdd,0x9d,0x2e,0x0c,0x7b,0x1f,0x31,0xa6, - 0x8a,0x27,0x03,0xb8,0x90,0x35,0x8f,0xa0,0x72,0x50,0x96,0xcd, - 0xa8,0xa7,0x37,0xfb,0x1b,0xfd,0x46,0xdb,0xa2,0x14,0x6c,0xca, - 0xe6,0x9b,0xb9,0x39,0x18,0x17,0x2b,0x0d,0x9b,0xcf,0x17,0xd6, - 0x1c,0x90,0x73,0xe5,0x94,0x4d,0x37,0xf3,0xcd,0xf7,0xe6,0xf0, - 0x4b,0x99,0xed,0x3e,0xd2,0xf7,0xfb,0x9b,0xee,0x95,0x96,0x4b, - 0xcb,0xd7,0x9e,0x5a,0x79,0xe3,0xb9,0x16,0x13,0xc3,0xd6,0x80, - 0x3a,0x12,0xee,0xaa,0x44,0xf4,0x1d,0x38,0x10,0x52,0x19,0xce, - 0x9f,0xea,0x12,0xe6,0x64,0x2d,0xe2,0xff,0x1c,0x49,0x88,0xd3, - 0x8d,0x2a,0x2d,0x9b,0x42,0x77,0xdc,0xa6,0x31,0x89,0xd1,0x1e, - 0xe4,0x2a,0xb0,0x25,0x09,0x20,0x1b,0x98,0x54,0xdc,0xa5,0x5d, - 0xfd,0xd6,0xf6,0x29,0xc3,0x02,0xbc,0xcd,0xb5,0xeb,0xa7,0x68, - 0x04,0x95,0xae,0x3e,0x18,0xa8,0x75,0x40,0xcc,0x73,0xdd,0x2f, - 0x8c,0x83,0x5a,0xe4,0x9a,0xa0,0x99,0xed,0xd3,0x4f,0xbf,0x16, - 0x8b,0xc8,0x88,0x13,0xe0,0xa2,0x12,0xf0,0x28,0x89,0x06,0x45, - 0xd5,0x65,0x93,0xf4,0xe1,0x0e,0x76,0x03,0x38,0x12,0xb3,0x6f, - 0x89,0x3c,0xab,0x23,0x59,0x0c,0x24,0xeb,0x49,0x77,0x22,0x49, - 0x24,0xa1,0x43,0x76,0x11,0xc3,0x1e,0x63,0xe6,0x2f,0x11,0xc1, - 0x9b,0x14,0xf7,0x0d,0xbc,0xae,0x00,0x77,0xcf,0x2f,0x7d,0x7a, - 0xe5,0xe7,0x17,0x01,0x2e,0x3e,0xbd,0x5e,0x26,0xfd,0x36,0xda, - 0x8c,0xf2,0x0c,0x37,0x92,0xd9,0x57,0x09,0x19,0x3c,0xb0,0x82, - 0x06,0x40,0x30,0x11,0x41,0x65,0xa3,0x6c,0x54,0x94,0x79,0x0e, - 0xdc,0x54,0xd8,0x73,0xe4,0x05,0xec,0xcf,0x8b,0xec,0x39,0x83, - 0xf1,0x6b,0x44,0x97,0xcd,0x72,0xc5,0x3e,0xf0,0x12,0xe7,0x4c, - 0x23,0xee,0x69,0xf7,0xcb,0xe6,0x1d,0xaa,0xf6,0xad,0x39,0xb6, - 0x11,0x9b,0x2c,0x37,0x4d,0x53,0x7f,0x66,0xc0,0xdb,0xb6,0xdb, - 0xa0,0x73,0x75,0x02,0x2e,0x46,0x6a,0x58,0xe3,0x38,0xd0,0x87, - 0xea,0x3c,0x74,0xab,0xf0,0xc1,0x97,0x30,0x01,0xa4,0x96,0x5b, - 0x6f,0x11,0xb0,0x26,0x9e,0x5b,0x19,0x91,0x5e,0x0f,0xf8,0xfa, - 0x1a,0x1a,0x43,0x21,0x6d,0x98,0x79,0x12,0x41,0xf4,0x19,0xde, - 0xf4,0xa8,0x3a,0x8f,0x0a,0xc1,0xd3,0x78,0x78,0x9d,0x95,0x06, - 0x2b,0xcc,0x31,0x9c,0x5d,0x56,0x97,0x01,0xf7,0xc5,0xe9,0xed, - 0x79,0x93,0xe3,0x69,0x93,0xe1,0xa4,0x3d,0xaa,0x3c,0x6d,0xe2, - 0x87,0x4d,0xe8,0xda,0xc9,0x29,0xb2,0x05,0x00,0x4d,0x3f,0x06, - 0x17,0x27,0x90,0x05,0x55,0x36,0xda,0xe6,0x25,0x09,0xc4,0x75, - 0x63,0xff,0x12,0xde,0x07,0x5f,0x54,0x9f,0xeb,0xb2,0x77,0x48, - 0x84,0x5c,0x8d,0xbb,0x49,0x0d,0x07,0x94,0x08,0xd7,0xb3,0x60, - 0xb4,0x7b,0xcd,0xde,0x03,0xac,0xc7,0x00,0x84,0x38,0x3d,0x0e, - 0x4f,0x88,0x6e,0xb7,0xe9,0x31,0x5f,0x3c,0xd5,0xd3,0xa2,0xbb, - 0xaf,0x0e,0xb8,0xf3,0xb3,0x74,0xa9,0x78,0x13,0x03,0x1b,0x10, - 0xd8,0x40,0xb8,0x4a,0x3c,0x41,0x40,0x30,0x9d,0xbe,0x44,0xfe, - 0xa7,0x12,0x91,0x6e,0x85,0xe2,0xac,0x3d,0xd8,0xa3,0x39,0x02, - 0xd5,0x44,0xf4,0x1e,0x8c,0x3b,0xdd,0x0a,0x51,0x62,0x3c,0xec, - 0x23,0x62,0xf8,0xc2,0x83,0x61,0x47,0xe7,0x4f,0x30,0xa6,0xe2, - 0xf0,0xe4,0xff,0xe5,0xef,0xb0,0x3b,0x02,0xb8,0x40,0x73,0xec, - 0x2b,0x1a,0xee,0xab,0xf5,0xa7,0x56,0xf4,0xd9,0x27,0x88,0x41, - 0xc1,0x76,0xbb,0xdf,0x45,0x50,0x3d,0x79,0x52,0xa2,0xb1,0xba, - 0x0e,0x7b,0x58,0xae,0x2c,0xca,0x47,0x81,0x99,0x64,0x95,0xec, - 0xaf,0x87,0x5f,0xe3,0x66,0x13,0xa2,0x47,0xac,0xfa,0x2b,0xdf, - 0xbd,0xad,0x5a,0x29,0x3a,0xcc,0xf4,0xf2,0x09,0x23,0x02,0x89, - 0x68,0x86,0x45,0xb8,0x2f,0xaf,0xd7,0x61,0xcc,0x49,0x95,0xb8, - 0xd4,0x51,0x0b,0x07,0x8d,0x46,0xfe,0x9d,0x9c,0x85,0xc9,0xea, - 0xe4,0x00,0xe7,0x59,0xfd,0x15,0xda,0x3d,0xb1,0x96,0xa0,0x2e, - 0x34,0xc6,0x3f,0x71,0xfa,0x4f,0x64,0x21,0xc3,0xdd,0xdd,0x7e, - 0xa3,0x5c,0xef,0xc6,0xeb,0xfd,0xbc,0x9b,0x34,0x53,0x5e,0xe0, - 0xc4,0xf6,0xa0,0x77,0xb3,0x4d,0x2f,0x0c,0xb0,0x80,0x50,0xad, - 0x64,0xed,0xe3,0x51,0x88,0x19,0xc9,0xf9,0xdc,0x17,0x7c,0x6b, - 0xf6,0x4d,0xf3,0xbe,0x7c,0xd3,0xee,0x96,0xfc,0xdd,0x1b,0xb7, - 0xeb,0x36,0xd3,0xbf,0xe5,0xd7,0x7f,0x6f,0xff,0xe3,0xb3,0x8d, - 0x09,0x62,0xb2,0x75,0xa2,0xd1,0x4e,0xd2,0x16,0x57,0x99,0x1b, - 0x5b,0xb2,0xb1,0x2e,0x71,0x67,0xe3,0x65,0x56,0x14,0x45,0x2e, - 0x72,0x5e,0x72,0x1b,0x97,0x8e,0xff,0xcf,0x78,0x08,0x44,0x08, - 0x45,0xc8,0x23,0x79,0x35,0x04,0x22,0x8b,0x41,0x28,0xa0,0xf3, - 0x22,0xce,0x2a,0xf2,0xac,0xcc,0x62,0xd3,0x88,0x8d,0xd8,0x79, - 0x76,0x5f,0x52,0x3d,0x14,0xa1,0x50,0x10,0x36,0xe4,0x31,0x62, - 0x5d,0xc3,0x81,0x6e,0x81,0x72,0x55,0x91,0x3e,0x26,0xa1,0x1c, - 0x8c,0x50,0x74,0xb1,0x75,0xb8,0x15,0x8c,0x91,0xc8,0x1e,0x5e, - 0xbc,0x41,0xde,0x10,0x8f,0xdb,0xf0,0x72,0x7c,0x61,0x5c,0xf2, - 0x94,0x85,0x0b,0xd6,0xe2,0x37,0x07,0x72,0x3c,0xbf,0x00,0x45, - 0x31,0x9e,0x2d,0xb6,0x26,0x26,0x9b,0x8b,0x0e,0xe0,0xb9,0x66, - 0x4e,0xf8,0xef,0xc4,0x2f,0x21,0x48,0xff,0xc2,0x91,0xef,0xfe, - 0x0b,0x06,0x62,0xc2,0xe3,0x11,0x13,0x00,0x00, -}; - -const GFXglyph Oswald_Medium20pt7bGlyphs[] PROGMEM = { - { 0, 1, 1, 10, 0, 0 }, // 0x20 ' ' - { 1, 5, 32, 9, 2, -31 }, // 0x21 '!' - { 21, 11, 11, 12, 1, -31 }, // 0x22 '"' - { 37, 17, 32, 20, 2, -31 }, // 0x23 '#' - { 105, 17, 39, 19, 1, -34 }, // 0x24 '$' - { 188, 34, 32, 37, 2, -31 }, // 0x25 '%' - { 324, 19, 32, 23, 2, -31 }, // 0x26 '&' - { 400, 4, 11, 6, 1, -31 }, // 0x27 ''' - { 406, 8, 39, 13, 3, -31 }, // 0x28 '(' - { 445, 9, 39, 12, 1, -31 }, // 0x29 ')' - { 489, 13, 14, 16, 2, -31 }, // 0x2A '*' - { 512, 15, 16, 17, 1, -23 }, // 0x2B '+' - { 542, 5, 10, 8, 2, -4 }, // 0x2C ',' - { 549, 10, 3, 12, 1, -12 }, // 0x2D '-' - { 553, 5, 5, 9, 2, -4 }, // 0x2E '.' - { 557, 13, 32, 16, 1, -31 }, // 0x2F '/' - { 609, 17, 32, 21, 2, -31 }, // 0x30 '0' - { 677, 10, 32, 15, 1, -31 }, // 0x31 '1' - { 717, 16, 32, 19, 2, -31 }, // 0x32 '2' - { 781, 16, 32, 19, 2, -31 }, // 0x33 '3' - { 845, 18, 32, 20, 1, -31 }, // 0x34 '4' - { 917, 16, 32, 19, 2, -31 }, // 0x35 '5' - { 981, 17, 32, 20, 2, -31 }, // 0x36 '6' - { 1049, 14, 32, 16, 1, -31 }, // 0x37 '7' - { 1105, 16, 32, 20, 2, -31 }, // 0x38 '8' - { 1169, 16, 32, 20, 2, -31 }, // 0x39 '9' - { 1233, 6, 18, 9, 2, -20 }, // 0x3A ':' - { 1247, 6, 25, 10, 2, -21 }, // 0x3B ';' - { 1266, 11, 17, 15, 2, -24 }, // 0x3C '<' - { 1290, 13, 11, 17, 2, -21 }, // 0x3D '=' - { 1308, 12, 17, 15, 2, -24 }, // 0x3E '>' - { 1334, 15, 32, 19, 2, -31 }, // 0x3F '?' - { 1394, 33, 37, 36, 2, -31 }, // 0x40 '@' - { 1547, 19, 32, 20, 1, -31 }, // 0x41 'A' - { 1623, 18, 32, 22, 2, -31 }, // 0x42 'B' - { 1695, 18, 32, 21, 2, -31 }, // 0x43 'C' - { 1767, 18, 32, 22, 2, -31 }, // 0x44 'D' - { 1839, 14, 32, 17, 2, -31 }, // 0x45 'E' - { 1895, 13, 32, 16, 2, -31 }, // 0x46 'F' - { 1947, 18, 32, 22, 2, -31 }, // 0x47 'G' - { 2019, 18, 32, 23, 2, -31 }, // 0x48 'H' - { 2091, 5, 32, 11, 3, -31 }, // 0x49 'I' - { 2111, 10, 33, 13, 0, -31 }, // 0x4A 'J' - { 2153, 19, 32, 21, 2, -31 }, // 0x4B 'K' - { 2229, 14, 32, 16, 2, -31 }, // 0x4C 'L' - { 2285, 22, 32, 27, 2, -31 }, // 0x4D 'M' - { 2373, 17, 32, 21, 2, -31 }, // 0x4E 'N' - { 2441, 18, 32, 22, 2, -31 }, // 0x4F 'O' - { 2513, 18, 32, 21, 2, -31 }, // 0x50 'P' - { 2585, 18, 38, 22, 2, -31 }, // 0x51 'Q' - { 2671, 18, 32, 22, 2, -31 }, // 0x52 'R' - { 2743, 16, 32, 19, 2, -31 }, // 0x53 'S' - { 2807, 15, 32, 17, 1, -31 }, // 0x54 'T' - { 2867, 18, 32, 22, 2, -31 }, // 0x55 'U' - { 2939, 18, 32, 20, 1, -31 }, // 0x56 'V' - { 3011, 26, 32, 28, 1, -31 }, // 0x57 'W' - { 3115, 19, 32, 20, 0, -31 }, // 0x58 'X' - { 3191, 19, 32, 19, 0, -31 }, // 0x59 'Y' - { 3267, 15, 32, 17, 1, -31 }, // 0x5A 'Z' - { 3327, 9, 39, 13, 2, -31 }, // 0x5B '[' - { 3371, 13, 32, 16, 1, -31 }, // 0x5C '\' - { 3423, 9, 39, 12, 1, -31 }, // 0x5D ']' - { 3467, 16, 13, 18, 1, -31 }, // 0x5E '^' - { 3493, 14, 4, 14, 0, 3 }, // 0x5F '_' - { 3500, 8, 8, 11, 2, -31 }, // 0x60 '`' - { 3508, 15, 23, 17, 1, -22 }, // 0x61 'a' - { 3552, 15, 32, 19, 2, -31 }, // 0x62 'b' - { 3612, 14, 23, 17, 2, -22 }, // 0x63 'c' - { 3653, 15, 32, 19, 2, -31 }, // 0x64 'd' - { 3713, 14, 23, 17, 2, -22 }, // 0x65 'e' - { 3754, 11, 31, 12, 1, -30 }, // 0x66 'f' - { 3797, 18, 31, 18, 1, -23 }, // 0x67 'g' - { 3867, 15, 32, 19, 2, -31 }, // 0x68 'h' - { 3927, 6, 31, 10, 2, -30 }, // 0x69 'i' - { 3951, 9, 37, 10, -1, -30 }, // 0x6A 'j' - { 3993, 16, 32, 18, 2, -31 }, // 0x6B 'k' - { 4057, 6, 32, 10, 2, -31 }, // 0x6C 'l' - { 4081, 24, 23, 28, 2, -22 }, // 0x6D 'm' - { 4150, 15, 23, 19, 2, -22 }, // 0x6E 'n' - { 4194, 14, 23, 18, 2, -22 }, // 0x6F 'o' - { 4235, 15, 30, 19, 2, -22 }, // 0x70 'p' - { 4292, 15, 30, 19, 2, -22 }, // 0x71 'q' - { 4349, 11, 23, 14, 2, -22 }, // 0x72 'r' - { 4381, 14, 23, 16, 1, -22 }, // 0x73 's' - { 4422, 11, 29, 13, 1, -28 }, // 0x74 't' - { 4462, 14, 23, 19, 2, -22 }, // 0x75 'u' - { 4503, 15, 23, 16, 0, -22 }, // 0x76 'v' - { 4547, 21, 23, 23, 1, -22 }, // 0x77 'w' - { 4608, 16, 23, 16, 0, -22 }, // 0x78 'x' - { 4654, 16, 29, 16, 0, -22 }, // 0x79 'y' - { 4712, 13, 23, 15, 1, -22 }, // 0x7A 'z' - { 4750, 10, 40, 13, 2, -31 }, // 0x7B '{' - { 4800, 4, 38, 10, 3, -31 }, // 0x7C '|' - { 4819, 10, 40, 14, 2, -31 }, // 0x7D '}' - { 4869, 16, 6, 18, 1, -18 } }; // 0x7E '~' - -// const GFXfont Oswald_Medium20pt7b PROGMEM = { -// (uint8_t *)Oswald_Medium20pt7bBitmaps, -// (GFXglyph *)Oswald_Medium20pt7bGlyphs, -// 0x20, 0x7E, 58 }; - -// // Approx. 5553 bytes - - -// Font properties -static constexpr FontData Oswald_Medium20pt7b_Properties = { - Oswald_Medium20pt7bBitmaps_Gzip, - Oswald_Medium20pt7bGlyphs, - sizeof(Oswald_Medium20pt7bBitmaps_Gzip), - 5553, // Original size - 0x20, // First char - 0x7E, // Last char - 58 // yAdvance -}; diff --git a/src/fonts/oswald-medium30.h b/src/fonts/oswald-medium30.h deleted file mode 100644 index 3cab489..0000000 --- a/src/fonts/oswald-medium30.h +++ /dev/null @@ -1,497 +0,0 @@ -#pragma once - -#include -#include -#include "fonts.hpp" - -const uint8_t Oswald_Medium30pt7bBitmaps_Gzip[] = { - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xcd, 0x5a, - 0xbb, 0x72, 0x23, 0x3b, 0x92, 0x05, 0xb7, 0x8c, 0x72, 0x26, 0x1a, 0x63, - 0x5e, 0x63, 0xe2, 0x62, 0x3f, 0x61, 0xcc, 0x36, 0xee, 0x08, 0xf7, 0x53, - 0xf6, 0x13, 0xc6, 0x6c, 0x43, 0x4b, 0x94, 0x82, 0x86, 0xbc, 0xd1, 0x27, - 0xf0, 0x53, 0x04, 0x86, 0x0c, 0x99, 0xfc, 0x83, 0x65, 0x31, 0x68, 0xd0, - 0x14, 0x14, 0x32, 0x08, 0x86, 0x4a, 0xc8, 0x3d, 0x27, 0xc1, 0xa7, 0xd4, - 0x52, 0xf7, 0xbd, 0xdd, 0x3b, 0xb1, 0x25, 0x50, 0x55, 0x85, 0x42, 0xe1, - 0x91, 0x48, 0x9c, 0x3c, 0x99, 0x28, 0x23, 0x3c, 0x0a, 0x8f, 0xf1, 0xee, - 0xb8, 0xac, 0xc7, 0x6f, 0x7a, 0x7c, 0xd6, 0xc3, 0x18, 0x23, 0xbb, 0xa3, - 0x78, 0x71, 0x72, 0xb3, 0xb8, 0x7f, 0x58, 0x6d, 0x96, 0xcf, 0xe9, 0x25, - 0x8f, 0x87, 0x8b, 0xb1, 0xbb, 0xb0, 0xd3, 0x76, 0x3e, 0x59, 0xcf, 0x56, - 0xfd, 0x63, 0xff, 0x25, 0xfd, 0x66, 0x46, 0x83, 0xeb, 0x42, 0xdb, 0xbb, - 0x49, 0x6e, 0xfb, 0x61, 0x94, 0xbd, 0x19, 0xdb, 0xe8, 0x26, 0x09, 0x37, - 0x0d, 0x6e, 0x8a, 0x8b, 0xbe, 0x4d, 0x76, 0x96, 0x9b, 0x34, 0x36, 0x28, - 0xe9, 0xdb, 0x25, 0x2a, 0x0e, 0x22, 0x0b, 0x91, 0x8d, 0xc8, 0x0b, 0x6e, - 0x76, 0xaf, 0x15, 0x1b, 0xfd, 0x35, 0x4a, 0x0e, 0x28, 0x69, 0xf7, 0x3d, - 0x90, 0x5b, 0x91, 0x07, 0x91, 0x67, 0xf4, 0xa5, 0xd6, 0x79, 0x6c, 0xc0, - 0xb2, 0x81, 0x80, 0x3a, 0xd1, 0x40, 0x7f, 0xda, 0x40, 0xef, 0xee, 0x72, - 0x9b, 0x0a, 0x4b, 0x9a, 0xbf, 0x19, 0xf3, 0xc9, 0x98, 0xd6, 0x98, 0xa6, - 0x33, 0xa3, 0x68, 0xda, 0xc1, 0x38, 0xe9, 0x9c, 0xf4, 0x4e, 0xb2, 0x43, - 0x95, 0x22, 0x76, 0x90, 0x79, 0x76, 0xeb, 0xdc, 0x3e, 0x0d, 0xcd, 0x4b, - 0x19, 0x15, 0x31, 0x12, 0xba, 0x70, 0x1b, 0xff, 0xe6, 0x92, 0xb1, 0x83, - 0x69, 0x8a, 0x19, 0x49, 0x67, 0xa4, 0x37, 0x7e, 0x30, 0x56, 0x4c, 0x23, - 0xd1, 0x48, 0x7a, 0x73, 0xd3, 0xd6, 0x62, 0x01, 0xc5, 0xf0, 0x5a, 0xfe, - 0xd2, 0xc8, 0x30, 0x12, 0x54, 0x25, 0x5d, 0x90, 0x58, 0x9b, 0xb3, 0xcf, - 0x43, 0xbb, 0x95, 0xeb, 0x21, 0x50, 0xaa, 0xc5, 0x4a, 0x69, 0xa4, 0x18, - 0x24, 0x37, 0x18, 0x93, 0x8c, 0xf9, 0xfc, 0xaa, 0xaf, 0x68, 0x1a, 0xb9, - 0xa8, 0xfd, 0xd2, 0x98, 0x20, 0xc6, 0x76, 0xe8, 0x78, 0x42, 0x16, 0xdf, - 0xba, 0xe4, 0x0c, 0xf5, 0xcc, 0xa2, 0xb0, 0x0c, 0xc4, 0xdc, 0x21, 0x6b, - 0xdc, 0x64, 0x66, 0xc5, 0x30, 0x62, 0x96, 0xed, 0xc7, 0x78, 0x71, 0x34, - 0x20, 0xcb, 0xf6, 0xfe, 0x2a, 0xa1, 0xc6, 0x16, 0x02, 0x32, 0xbe, 0x2b, - 0xc8, 0x6a, 0x93, 0x9b, 0xa1, 0xfa, 0xd2, 0x64, 0x64, 0xd9, 0x18, 0x6c, - 0xc4, 0x73, 0xcb, 0x2c, 0x3f, 0xc9, 0x17, 0xe8, 0x44, 0x66, 0x16, 0x1a, - 0x5e, 0x22, 0xcb, 0x4a, 0xbe, 0x68, 0x30, 0x18, 0x4c, 0x10, 0x86, 0x21, - 0xb3, 0x1c, 0xa4, 0x93, 0xfe, 0x02, 0xd9, 0xa3, 0xd8, 0xde, 0x61, 0x98, - 0x66, 0x94, 0xc3, 0x0d, 0x0a, 0x5e, 0xd8, 0xbe, 0xe0, 0xdd, 0xbb, 0xec, - 0x22, 0xb3, 0x9a, 0xac, 0x59, 0x01, 0x59, 0xb3, 0xa1, 0xed, 0x91, 0xe5, - 0x3b, 0x0c, 0x16, 0xea, 0xe0, 0xd0, 0x83, 0x58, 0x38, 0x40, 0x14, 0x65, - 0xa7, 0xd0, 0x5f, 0x4c, 0x4e, 0xd4, 0x57, 0xb2, 0xbe, 0xe2, 0xd1, 0x9f, - 0xde, 0x60, 0x2e, 0x67, 0x78, 0x25, 0x37, 0x03, 0xb2, 0x1c, 0xfa, 0xc3, - 0xac, 0x56, 0x98, 0x45, 0xa9, 0x20, 0xab, 0xc5, 0x1c, 0xa0, 0x6e, 0xdf, - 0x1b, 0xde, 0x72, 0x1a, 0x32, 0x24, 0xd5, 0x43, 0xfa, 0x9d, 0x45, 0x39, - 0xb1, 0xa9, 0x4d, 0xbe, 0xf3, 0x57, 0x03, 0xeb, 0x63, 0xcd, 0x68, 0xa3, - 0x41, 0xab, 0x2e, 0x16, 0x68, 0x5c, 0x4f, 0x0d, 0x72, 0xf7, 0xc9, 0x14, - 0x6f, 0x9a, 0xe7, 0x6c, 0xec, 0x02, 0x93, 0x98, 0x75, 0x2e, 0x6d, 0xa6, - 0xb0, 0x4c, 0xc3, 0x1e, 0x27, 0x37, 0x91, 0x6e, 0xf0, 0xa5, 0x5d, 0x49, - 0xf2, 0x6e, 0x31, 0xdb, 0x96, 0xb1, 0x9b, 0xaf, 0x72, 0x09, 0x76, 0xbd, - 0x4e, 0xc1, 0xfb, 0x2b, 0xd9, 0x0e, 0xad, 0xdc, 0xf4, 0x1e, 0xdd, 0x94, - 0x55, 0x6e, 0xa1, 0xf4, 0xae, 0x2f, 0x23, 0xb9, 0x86, 0x92, 0xb9, 0xa5, - 0x14, 0xe8, 0xf1, 0x13, 0x7e, 0x37, 0xf2, 0x34, 0x78, 0xb1, 0x3d, 0xf4, - 0xc1, 0xfc, 0xd3, 0x7c, 0xa6, 0x7a, 0x2f, 0x6e, 0xc7, 0x2f, 0xcf, 0xeb, - 0xf9, 0xf4, 0xe2, 0x32, 0x99, 0x2f, 0x36, 0x16, 0x9b, 0xe4, 0x66, 0x08, - 0x6d, 0x46, 0x87, 0x51, 0x03, 0xba, 0xce, 0xb3, 0xe0, 0x7e, 0x86, 0x47, - 0x61, 0x72, 0xc8, 0xc4, 0x48, 0x38, 0x0a, 0xbd, 0xd9, 0x3f, 0xa9, 0xc5, - 0xf6, 0x8f, 0xeb, 0xbf, 0x62, 0x07, 0xdf, 0x0b, 0xc5, 0xfb, 0x2b, 0x56, - 0x0f, 0xcb, 0x66, 0x1f, 0x71, 0xef, 0xf4, 0x7d, 0x3e, 0xd9, 0x55, 0x32, - 0x9c, 0x55, 0xf2, 0xb5, 0x9b, 0x93, 0x86, 0xfd, 0x8c, 0x67, 0x3c, 0x9c, - 0x0c, 0xe1, 0xae, 0xf0, 0x51, 0x0f, 0xfd, 0x1d, 0x74, 0x22, 0x0c, 0xd4, - 0xcf, 0x76, 0xbf, 0x5c, 0x7e, 0x7e, 0x5a, 0xcd, 0x65, 0x1c, 0x38, 0xc8, - 0x7b, 0x49, 0x58, 0x20, 0x0e, 0x93, 0x42, 0x6d, 0x7f, 0x4e, 0x76, 0x1e, - 0x87, 0x71, 0xbb, 0xcc, 0x9f, 0xac, 0xf9, 0xfb, 0x7f, 0x72, 0x2a, 0x9b, - 0x9e, 0x0a, 0x7e, 0x71, 0x7e, 0xd9, 0xc8, 0xe9, 0x91, 0xde, 0x16, 0x38, - 0x5c, 0xee, 0xcb, 0xb4, 0xad, 0x75, 0x17, 0x97, 0x5f, 0xfe, 0x7e, 0xf2, - 0xd6, 0xfe, 0x82, 0x65, 0x2f, 0x8d, 0xeb, 0x4e, 0x4f, 0xb6, 0x6b, 0xd2, - 0xab, 0xd3, 0x18, 0xa7, 0xd1, 0xe9, 0x29, 0xe2, 0x74, 0xf1, 0xea, 0xd4, - 0xc6, 0x51, 0x3e, 0x3d, 0xa1, 0x27, 0xfe, 0xec, 0xe4, 0x28, 0x08, 0x23, - 0x1d, 0x74, 0xb1, 0xe1, 0x3a, 0x97, 0x2b, 0x91, 0xa5, 0x76, 0x66, 0x90, - 0x49, 0x09, 0x51, 0x7c, 0x0c, 0x0b, 0x60, 0x42, 0xc2, 0x12, 0x82, 0x32, - 0xa3, 0xcc, 0x11, 0x2c, 0xbc, 0xfc, 0xd0, 0x83, 0x97, 0xd2, 0x14, 0x19, - 0x49, 0x98, 0x89, 0x7f, 0x84, 0xbe, 0xc9, 0xb5, 0xc8, 0x4c, 0x24, 0x2a, - 0x0a, 0x45, 0xe2, 0x15, 0x30, 0xd1, 0x8c, 0xb1, 0x16, 0x72, 0x78, 0x3a, - 0x91, 0xee, 0x3d, 0xa6, 0xdf, 0xf5, 0xe8, 0x56, 0x27, 0xa3, 0xd2, 0x0c, - 0x6d, 0xfe, 0x73, 0xb7, 0x26, 0x44, 0x8c, 0x19, 0x5d, 0x1b, 0x69, 0xb3, - 0x18, 0x73, 0xc6, 0x98, 0xd1, 0x19, 0x8c, 0xf9, 0x36, 0x7a, 0x8c, 0xf9, - 0x21, 0xd9, 0x4d, 0x6e, 0x9f, 0x0f, 0x58, 0x4b, 0x31, 0xe1, 0x2d, 0xe3, - 0x23, 0x97, 0x30, 0x12, 0x60, 0x97, 0xc8, 0x4b, 0x14, 0x65, 0x6a, 0x33, - 0x31, 0xbb, 0x55, 0x20, 0xae, 0x09, 0x4a, 0x54, 0x13, 0xdf, 0xac, 0x09, - 0xef, 0xef, 0xaa, 0x50, 0x7b, 0xb1, 0x50, 0x93, 0xb1, 0x51, 0xab, 0x01, - 0xfb, 0x02, 0x94, 0x8d, 0x87, 0x99, 0x98, 0x68, 0xaf, 0xb6, 0x58, 0x64, - 0x72, 0x55, 0xd0, 0xe3, 0xdb, 0x2a, 0xbe, 0xde, 0x42, 0x45, 0x59, 0x66, - 0x18, 0x01, 0xc1, 0x50, 0x77, 0xe8, 0x34, 0xb1, 0xe2, 0x86, 0xaf, 0x03, - 0xe8, 0xa3, 0xc2, 0x3b, 0x0d, 0x08, 0x40, 0xb8, 0x63, 0x5f, 0xd1, 0x4b, - 0xf4, 0x6c, 0xff, 0x86, 0x74, 0x5e, 0xb1, 0x5e, 0xab, 0xda, 0x0d, 0x70, - 0xc4, 0x91, 0xfb, 0xc4, 0x99, 0xb8, 0xdf, 0xcf, 0x04, 0x9a, 0x8b, 0x44, - 0x2d, 0xa8, 0x30, 0x2d, 0x8c, 0xda, 0x0d, 0x0c, 0x97, 0x23, 0x8b, 0x04, - 0x1f, 0x35, 0x2c, 0xbd, 0x09, 0x6a, 0xaa, 0x1a, 0x58, 0x80, 0xff, 0xc6, - 0xda, 0xb9, 0x8d, 0xcd, 0x26, 0x9b, 0x01, 0x0b, 0x68, 0xda, 0xb7, 0xab, - 0xc1, 0x0c, 0xa1, 0x73, 0x37, 0xa9, 0x5d, 0x16, 0x33, 0x78, 0x98, 0x4d, - 0x98, 0x5e, 0x81, 0x1d, 0xee, 0xb1, 0x20, 0x5b, 0x5d, 0xfa, 0x0a, 0x0b, - 0x3d, 0xd6, 0x29, 0x16, 0xa9, 0xbc, 0x3d, 0x12, 0xa5, 0x05, 0xd9, 0x2a, - 0x68, 0xf6, 0x0a, 0x72, 0x18, 0x2e, 0xc6, 0xc3, 0xc1, 0x9c, 0x3e, 0x0a, - 0x98, 0xbe, 0xaf, 0x26, 0xbc, 0x00, 0x45, 0x3a, 0x4f, 0xa5, 0x26, 0x1f, - 0x0b, 0x75, 0x9d, 0x53, 0xaf, 0xa9, 0x40, 0xe9, 0x45, 0x67, 0xbb, 0xe8, - 0x84, 0xbf, 0x4d, 0xf2, 0x3a, 0x69, 0x79, 0x4c, 0x90, 0xb6, 0xe5, 0x69, - 0xab, 0xa1, 0xe0, 0x3d, 0xa5, 0x46, 0xdb, 0x57, 0x95, 0x8c, 0x4b, 0x60, - 0xbf, 0xb0, 0xf6, 0xd3, 0x09, 0x2d, 0x9c, 0xf6, 0x6e, 0x5e, 0x57, 0x43, - 0xe6, 0xb8, 0x8e, 0xf3, 0x89, 0x61, 0xb9, 0xd5, 0x60, 0x37, 0x72, 0xfd, - 0x2c, 0x2b, 0xea, 0x00, 0xfb, 0x26, 0xa1, 0x97, 0xdb, 0xde, 0xeb, 0x6a, - 0xdc, 0x29, 0x00, 0x7b, 0x29, 0xe7, 0xd3, 0x59, 0xf5, 0x75, 0x40, 0xa7, - 0x30, 0x9d, 0x80, 0xc5, 0x1b, 0x55, 0xa4, 0xd3, 0x85, 0xa5, 0x88, 0xf4, - 0x56, 0xce, 0xb4, 0x4a, 0x6d, 0x42, 0xeb, 0xe8, 0x89, 0x7b, 0x75, 0x53, - 0x28, 0xef, 0x7a, 0x13, 0x47, 0x5f, 0xbd, 0x01, 0xa0, 0x1c, 0x6e, 0xda, - 0x93, 0x1b, 0x73, 0x72, 0x23, 0x87, 0x1b, 0x2c, 0x89, 0x56, 0xbb, 0x0b, - 0xb2, 0xe1, 0x29, 0x35, 0x62, 0x33, 0x2c, 0x00, 0x12, 0x05, 0x7a, 0x2e, - 0xdf, 0x80, 0x34, 0xd2, 0xa7, 0x93, 0xc1, 0xaf, 0x07, 0xf2, 0x13, 0x0a, - 0xe0, 0xfc, 0xf5, 0x59, 0x7d, 0xf7, 0xf8, 0x62, 0xd9, 0xa7, 0xb3, 0xda, - 0xae, 0x84, 0xf5, 0x90, 0xd6, 0xf0, 0xad, 0x5a, 0x55, 0xb3, 0x9b, 0x2a, - 0x60, 0x60, 0x3a, 0x4c, 0x55, 0xcf, 0xa9, 0x02, 0x03, 0xda, 0x4d, 0xd5, - 0x11, 0x0f, 0x5e, 0x23, 0xda, 0x11, 0x28, 0x4a, 0xf3, 0x22, 0x4d, 0x09, - 0x6b, 0x81, 0x16, 0x4f, 0x75, 0x11, 0x71, 0xbe, 0x03, 0xf8, 0xda, 0xdd, - 0xeb, 0xb9, 0xc5, 0x7a, 0x3c, 0x81, 0x16, 0xac, 0xbc, 0x6e, 0x37, 0x55, - 0x6f, 0x30, 0xf0, 0x38, 0x55, 0xe6, 0x70, 0xec, 0x18, 0x67, 0x2a, 0xbb, - 0xc3, 0x9c, 0x1f, 0x7b, 0x42, 0xfc, 0xe9, 0xd3, 0xaf, 0x17, 0xc3, 0x97, - 0x7f, 0x1a, 0xf3, 0x3b, 0x2c, 0xf8, 0x25, 0xa6, 0x22, 0xc4, 0x90, 0x3c, - 0xc6, 0xed, 0x8b, 0x2f, 0x16, 0xe0, 0x0b, 0x2b, 0xe8, 0x23, 0x2e, 0xa4, - 0x0f, 0x05, 0xf2, 0x0c, 0xe0, 0x05, 0x28, 0xd3, 0xd2, 0xc2, 0x80, 0xd9, - 0xfd, 0x7e, 0xa2, 0x1b, 0xa7, 0x4d, 0x9c, 0xdb, 0x3a, 0x68, 0xd3, 0x67, - 0xda, 0xa3, 0x0c, 0xf9, 0x79, 0x48, 0xf3, 0x8a, 0x0b, 0xe0, 0x0a, 0x33, - 0x03, 0x3e, 0x03, 0x23, 0x64, 0x93, 0x85, 0x94, 0x1d, 0xe4, 0x71, 0x03, - 0x35, 0xec, 0x50, 0xa6, 0x43, 0xe1, 0xce, 0x80, 0xb0, 0x01, 0x4c, 0x4e, - 0x27, 0x11, 0x93, 0xc2, 0x34, 0x91, 0x30, 0x3a, 0x9b, 0x32, 0x88, 0xe6, - 0xcb, 0x61, 0xf9, 0x51, 0x75, 0x0a, 0x97, 0x0a, 0x52, 0xab, 0xa0, 0x0b, - 0x00, 0x06, 0xba, 0x01, 0xfc, 0x38, 0x7d, 0x0a, 0xbb, 0xc3, 0x57, 0xd2, - 0xe9, 0xf1, 0xd5, 0x02, 0xb5, 0xcc, 0xb8, 0x8e, 0x8f, 0xd7, 0x2d, 0x66, - 0x41, 0x25, 0x3d, 0xe8, 0x35, 0x99, 0x1b, 0xfe, 0x67, 0xc2, 0x69, 0x2b, - 0x0a, 0x84, 0xa4, 0x71, 0xe0, 0x5c, 0x99, 0x8d, 0x43, 0xb8, 0x9e, 0xc5, - 0xc1, 0xda, 0xc8, 0x30, 0x21, 0x42, 0xa8, 0x7e, 0x03, 0x80, 0x06, 0xfd, - 0x87, 0x0a, 0x2e, 0x26, 0x29, 0x90, 0x10, 0x8e, 0xc1, 0xff, 0x21, 0x9f, - 0x6b, 0xac, 0x60, 0xf0, 0xb3, 0x0c, 0xbe, 0x73, 0x95, 0x87, 0x66, 0xb0, - 0xf1, 0xc2, 0xc3, 0x3a, 0x25, 0x3b, 0x8d, 0xc0, 0xc3, 0x66, 0x9d, 0x40, - 0x8c, 0xcd, 0x16, 0xdc, 0xd2, 0xc5, 0x0b, 0x30, 0x65, 0xb8, 0x24, 0xd3, - 0x0e, 0x4b, 0xba, 0x59, 0x83, 0x12, 0x8e, 0xf1, 0x00, 0x8c, 0xad, 0x1b, - 0x83, 0xe2, 0xa0, 0xc0, 0x2d, 0xca, 0xe7, 0xf6, 0x01, 0x0f, 0xca, 0xe8, - 0x09, 0x0f, 0xc0, 0x5a, 0xf5, 0x01, 0x78, 0x1e, 0xe8, 0xb6, 0xbb, 0x21, - 0xc0, 0x82, 0xbd, 0x80, 0xaa, 0xc1, 0xe5, 0xc0, 0xcc, 0xcd, 0xb2, 0xeb, - 0x80, 0x27, 0x28, 0xe3, 0xc0, 0xf4, 0x50, 0x27, 0x66, 0xa6, 0x43, 0xdf, - 0xee, 0x40, 0x41, 0x7b, 0x90, 0x5a, 0x4e, 0x24, 0x8f, 0xa0, 0xff, 0xa1, - 0xa7, 0x14, 0x48, 0xcd, 0xc2, 0x60, 0x99, 0x95, 0xaa, 0x8c, 0x6a, 0xa9, - 0x6c, 0x7e, 0xad, 0xea, 0x08, 0x2f, 0x40, 0x21, 0x04, 0x76, 0x00, 0x42, - 0xd2, 0x1b, 0x55, 0x54, 0x55, 0x1c, 0x50, 0x6c, 0x43, 0x71, 0xf1, 0x2d, - 0x47, 0xb4, 0x06, 0x33, 0xc6, 0xa5, 0xcf, 0xea, 0x95, 0x38, 0xae, 0x8c, - 0xac, 0xe4, 0xd8, 0x63, 0xfa, 0x80, 0xf7, 0x0e, 0xcc, 0x16, 0x5a, 0xdd, - 0x6e, 0x30, 0xb7, 0xb7, 0x5d, 0xf3, 0x02, 0xa0, 0x99, 0x03, 0x83, 0x7c, - 0xd7, 0x3e, 0x42, 0x63, 0x6f, 0x7a, 0x32, 0x6c, 0xb7, 0xca, 0xf0, 0xd7, - 0xfa, 0x36, 0x09, 0xdd, 0x80, 0x66, 0x50, 0x16, 0x6b, 0x40, 0x02, 0xc1, - 0xfc, 0x22, 0x0c, 0x0a, 0xc6, 0x0a, 0xc5, 0x82, 0xc6, 0x41, 0xd2, 0xb8, - 0xf4, 0x8a, 0x82, 0xb0, 0x3a, 0x60, 0xb4, 0x26, 0x5c, 0xe3, 0x05, 0x1f, - 0xdd, 0x0a, 0x2f, 0xa0, 0x8a, 0x0c, 0x4b, 0xb5, 0x86, 0xfe, 0xfa, 0x88, - 0x35, 0x6c, 0xb0, 0xa0, 0x47, 0x9c, 0x75, 0xc7, 0x85, 0x8e, 0x45, 0x41, - 0xff, 0x87, 0x0b, 0xb9, 0xf8, 0x7b, 0xb9, 0xcf, 0x2d, 0xcc, 0x1a, 0x60, - 0xdb, 0x3e, 0x61, 0x6e, 0x61, 0xd6, 0xe6, 0xa9, 0xd9, 0x16, 0x13, 0xb0, - 0x8a, 0xd6, 0xa8, 0xb2, 0x3e, 0x5a, 0x61, 0x46, 0xc3, 0x95, 0xd4, 0xb7, - 0xd0, 0x30, 0x20, 0x83, 0x68, 0x42, 0x07, 0x6e, 0x35, 0xb4, 0x78, 0x2b, - 0xcc, 0x53, 0xfb, 0x82, 0xb7, 0x6e, 0x23, 0x40, 0x80, 0xca, 0xee, 0x45, - 0xfd, 0x04, 0xa1, 0xb7, 0x97, 0xe8, 0x34, 0xd5, 0x47, 0x0d, 0xf1, 0x6c, - 0xd1, 0x7b, 0x90, 0x1f, 0x2c, 0x0d, 0xa2, 0x03, 0x49, 0x8a, 0xe7, 0x80, - 0x8a, 0x0a, 0x51, 0xd1, 0x0d, 0x58, 0x41, 0xb3, 0x89, 0xe6, 0xd6, 0xc5, - 0x6d, 0x09, 0xfb, 0x80, 0x25, 0x2c, 0xab, 0xac, 0x3e, 0x1b, 0x2d, 0xc3, - 0x9b, 0x1b, 0x2e, 0x13, 0xb3, 0xa3, 0x05, 0x1f, 0xdc, 0xbc, 0x5f, 0x01, - 0x61, 0x0b, 0x6c, 0x21, 0x4c, 0xb3, 0x5f, 0x55, 0xe3, 0x89, 0xc1, 0x35, - 0x15, 0x10, 0x39, 0x8f, 0x0e, 0x95, 0x60, 0xa6, 0x88, 0xae, 0x14, 0x7b, - 0x52, 0xef, 0x5c, 0xe6, 0xf0, 0x2c, 0x20, 0x00, 0x0c, 0xea, 0x36, 0x02, - 0x33, 0xdb, 0xea, 0x77, 0x2a, 0xd4, 0xfd, 0xec, 0x1b, 0x20, 0x6b, 0x6d, - 0x47, 0x1b, 0xad, 0x5d, 0x54, 0x4f, 0x56, 0x1a, 0x15, 0xf4, 0x5b, 0x8e, - 0x21, 0xd5, 0x40, 0xbd, 0xf7, 0x0f, 0xd2, 0xcf, 0x27, 0xff, 0x3e, 0x2e, - 0x7c, 0xf2, 0xda, 0x47, 0x47, 0x04, 0x82, 0x41, 0xf5, 0xa0, 0xce, 0x30, - 0x0b, 0x36, 0x01, 0xd8, 0xfc, 0x79, 0x16, 0xed, 0xbe, 0x97, 0x35, 0x6d, - 0xff, 0x14, 0xa2, 0x7b, 0xa7, 0xd4, 0x47, 0x59, 0xd4, 0x92, 0x20, 0x27, - 0x33, 0x01, 0x3d, 0x72, 0x83, 0x5f, 0x01, 0xfc, 0x43, 0xe7, 0xa1, 0x87, - 0x50, 0x78, 0x4c, 0xa4, 0x7b, 0xa0, 0x07, 0x63, 0x54, 0x6f, 0x28, 0xc6, - 0x8e, 0xcb, 0x9c, 0xaa, 0x00, 0x68, 0xb3, 0x59, 0x09, 0x2c, 0x34, 0x02, - 0xfc, 0xd1, 0xec, 0x2a, 0xa1, 0x24, 0x67, 0xaa, 0x8c, 0x5f, 0xd3, 0x5e, - 0x89, 0x56, 0xf6, 0x8a, 0x6d, 0x9f, 0x07, 0xaa, 0x8a, 0x7f, 0x18, 0x2c, - 0x29, 0xcc, 0x54, 0x9e, 0x1f, 0x45, 0xc6, 0x4e, 0xe6, 0x33, 0x79, 0xcc, - 0xe8, 0x8a, 0xf9, 0x8d, 0xb8, 0xfe, 0x71, 0x1d, 0xdf, 0xf3, 0xe8, 0xbd, - 0xe3, 0x4f, 0x57, 0x78, 0xfe, 0xe8, 0x0f, 0x1e, 0x4d, 0x69, 0xe1, 0xb6, - 0xb8, 0xe4, 0x7b, 0x90, 0xb0, 0xab, 0x1f, 0xb8, 0x1d, 0xe9, 0x8d, 0xdf, - 0xc0, 0x4b, 0x98, 0x0a, 0x5c, 0xf6, 0x04, 0x44, 0x23, 0x44, 0x51, 0xac, - 0x15, 0x4a, 0xec, 0x23, 0x26, 0x13, 0x5c, 0x12, 0xfe, 0x3b, 0x40, 0x1e, - 0x90, 0x48, 0x07, 0x98, 0x5e, 0x30, 0x30, 0xff, 0x0a, 0xb7, 0xfe, 0x1e, - 0xbc, 0x1a, 0x6f, 0xf9, 0xde, 0xad, 0x07, 0xc5, 0xa8, 0xdb, 0xfe, 0x14, - 0x77, 0x14, 0x43, 0x1c, 0x17, 0x38, 0x96, 0x2f, 0x98, 0xcc, 0x16, 0x4b, - 0xdb, 0xf7, 0xfe, 0x0e, 0x6f, 0xa1, 0xfd, 0x56, 0x1d, 0x6f, 0x56, 0x48, - 0xd7, 0xdd, 0x2f, 0xd1, 0x1d, 0x6d, 0xcb, 0x66, 0xb0, 0x16, 0xd7, 0x83, - 0xa4, 0xee, 0x35, 0x09, 0x88, 0x26, 0x07, 0x44, 0xfb, 0xce, 0xe5, 0xf1, - 0xc3, 0xff, 0xce, 0x0f, 0xb2, 0x80, 0x29, 0x18, 0xe6, 0x1a, 0x6c, 0x73, - 0x0b, 0x3b, 0x5d, 0x02, 0xa0, 0x1c, 0x19, 0xa0, 0x64, 0x06, 0xd0, 0x18, - 0x91, 0x81, 0x59, 0x9d, 0x62, 0x82, 0x91, 0xe1, 0xb7, 0x50, 0xce, 0x12, - 0x80, 0xce, 0x53, 0x8c, 0x78, 0x8d, 0xc1, 0x23, 0xc3, 0x8d, 0x41, 0x82, - 0x16, 0x53, 0x69, 0x36, 0x6b, 0x89, 0x2f, 0xdb, 0x97, 0xe4, 0xc7, 0xe1, - 0xd2, 0x4e, 0xa7, 0x8b, 0xc9, 0x7a, 0xbd, 0x59, 0x6e, 0xb7, 0xdb, 0x3c, - 0x1e, 0x8f, 0x2f, 0xdc, 0x74, 0x7a, 0x73, 0x7d, 0xbf, 0x5e, 0x3d, 0x3d, - 0x6e, 0xf3, 0x30, 0x8c, 0xc7, 0xde, 0xbb, 0xe9, 0xf5, 0xfc, 0x7e, 0xbd, - 0x7c, 0x5a, 0x6e, 0x73, 0x40, 0x11, 0x57, 0x90, 0x21, 0xd7, 0xeb, 0x5e, - 0x90, 0xe1, 0xd3, 0x78, 0x0c, 0x12, 0x34, 0x9d, 0x48, 0x0b, 0x03, 0x3e, - 0xdb, 0x32, 0x9e, 0x31, 0x86, 0x5c, 0x17, 0x57, 0xa5, 0xdd, 0xc0, 0x3e, - 0xbf, 0x30, 0x88, 0x34, 0x86, 0xb1, 0x96, 0x0e, 0x04, 0xac, 0xf7, 0x70, - 0x18, 0x6c, 0x84, 0x47, 0xc5, 0x54, 0xf6, 0x49, 0x6a, 0xea, 0x34, 0xc5, - 0x7d, 0xea, 0x35, 0xa5, 0x7d, 0xca, 0x9a, 0xd4, 0xe5, 0x29, 0x45, 0xd3, - 0x38, 0x94, 0xa0, 0xc9, 0x6b, 0x24, 0xcf, 0xed, 0x93, 0xd5, 0xd4, 0x6a, - 0x6a, 0xf6, 0x49, 0xb9, 0x6f, 0x39, 0x32, 0xe7, 0xda, 0xb4, 0xaf, 0xe9, - 0x35, 0x92, 0x64, 0x45, 0x92, 0xf0, 0x54, 0x91, 0x64, 0x91, 0xce, 0x14, - 0xe9, 0x04, 0x49, 0xbc, 0xfc, 0xb4, 0x47, 0xaa, 0xf2, 0x31, 0xcc, 0x07, - 0x97, 0xab, 0x39, 0x9d, 0xa9, 0x8d, 0x57, 0xdc, 0xb7, 0xc4, 0x2c, 0xf5, - 0xce, 0x40, 0x25, 0xdf, 0x5a, 0x1d, 0x5a, 0x83, 0x50, 0xad, 0xce, 0xf3, - 0x50, 0x55, 0x3f, 0x2a, 0xf3, 0x3f, 0x18, 0x8d, 0x87, 0x9d, 0xd1, 0x68, - 0xe8, 0x95, 0xe3, 0x9d, 0x6a, 0xd7, 0xb2, 0xd6, 0x96, 0xc9, 0x0e, 0x45, - 0x9d, 0x4d, 0x28, 0xdd, 0x9f, 0xbd, 0xf9, 0xff, 0x21, 0x41, 0x79, 0x5f, - 0x82, 0x51, 0xe3, 0xbb, 0xe8, 0x70, 0xb3, 0x3b, 0x31, 0xaa, 0x68, 0x18, - 0x8d, 0x62, 0xc4, 0xb7, 0x31, 0xa7, 0xa4, 0x48, 0xf6, 0xa4, 0x68, 0x26, - 0xeb, 0x03, 0x29, 0xd2, 0xea, 0x3b, 0x88, 0xb2, 0x39, 0xd2, 0x1b, 0x0a, - 0x7e, 0xb1, 0xe7, 0x4b, 0x80, 0x2b, 0xac, 0x32, 0x9d, 0x96, 0xeb, 0xea, - 0x62, 0x41, 0x17, 0x41, 0xc5, 0x7a, 0x85, 0xab, 0x0a, 0x31, 0xb3, 0x03, - 0xe6, 0xf4, 0xe1, 0x8e, 0xb1, 0x9f, 0x4e, 0x6c, 0x72, 0x4b, 0x05, 0x39, - 0x0f, 0x02, 0x06, 0xe3, 0x2b, 0xf0, 0x9b, 0x6b, 0x85, 0xaf, 0x80, 0x47, - 0x63, 0x2c, 0xb9, 0x7a, 0x66, 0xa9, 0x2a, 0xc2, 0x75, 0xf1, 0x4b, 0x54, - 0xa6, 0x0e, 0x96, 0x9b, 0xe7, 0xf6, 0x89, 0x0e, 0x57, 0x87, 0xde, 0xfe, - 0xda, 0x56, 0xc3, 0x16, 0x7a, 0x8d, 0x9d, 0xd7, 0xc8, 0x86, 0x2b, 0xfb, - 0x78, 0x06, 0x15, 0x4a, 0x76, 0x19, 0xf1, 0x24, 0xe8, 0xe1, 0x13, 0x03, - 0xe8, 0xb0, 0x83, 0x30, 0x69, 0xaa, 0x4c, 0x70, 0x4f, 0x19, 0x20, 0x83, - 0x14, 0x80, 0x9c, 0xf4, 0xb9, 0x6f, 0x72, 0x58, 0xa9, 0x91, 0x1c, 0x9c, - 0x86, 0x71, 0x30, 0xe3, 0x70, 0x19, 0x76, 0xea, 0xf9, 0x95, 0xe3, 0x10, - 0x24, 0xfa, 0xf7, 0xa7, 0x9f, 0x65, 0x1d, 0xff, 0xc4, 0xa3, 0x66, 0xa7, - 0x18, 0xdf, 0x5c, 0xd4, 0x1d, 0xa1, 0x1e, 0x9e, 0x80, 0x04, 0xfa, 0xcc, - 0x86, 0xac, 0x7b, 0x0d, 0xb5, 0xf2, 0x1d, 0x3c, 0x00, 0x9c, 0xa2, 0xbb, - 0x1b, 0x46, 0x8c, 0x2b, 0xcd, 0x06, 0x3a, 0x01, 0x3c, 0x41, 0x7d, 0xe8, - 0x00, 0x10, 0x56, 0xbb, 0xd2, 0x6a, 0x88, 0x5e, 0xe0, 0x13, 0xd1, 0x05, - 0x63, 0x84, 0x1d, 0xed, 0xc2, 0xd5, 0x49, 0xe8, 0x08, 0x3c, 0x89, 0x0c, - 0x68, 0x9b, 0xf6, 0xcd, 0x16, 0x6c, 0x75, 0x1a, 0xd5, 0xd3, 0x58, 0xc4, - 0xd1, 0x8b, 0x86, 0xb3, 0x6a, 0x74, 0x5e, 0x15, 0x6a, 0xa7, 0x0c, 0x56, - 0x74, 0x97, 0x83, 0xbe, 0x4b, 0xa8, 0x6a, 0x00, 0xe5, 0xe1, 0x89, 0xbe, - 0x4d, 0x61, 0x3c, 0x89, 0xb1, 0x3b, 0x0d, 0x4d, 0xd0, 0x7d, 0x47, 0xb3, - 0x0c, 0x3a, 0x6e, 0x19, 0x75, 0x5c, 0x33, 0xec, 0x08, 0xf7, 0xae, 0x63, - 0x28, 0x63, 0x9f, 0xe5, 0x13, 0xda, 0x96, 0xd9, 0xe0, 0x61, 0x1a, 0x52, - 0x81, 0x8d, 0xb8, 0x83, 0xb1, 0x40, 0xe7, 0x98, 0x05, 0xf3, 0x91, 0x0a, - 0xec, 0xc8, 0x1d, 0x0c, 0x4a, 0x68, 0x1f, 0x9f, 0x56, 0xd9, 0xdd, 0xcf, - 0xe1, 0xce, 0xb9, 0x0b, 0x78, 0x76, 0x03, 0x9c, 0xbc, 0xa7, 0x27, 0xf8, - 0x7b, 0xf3, 0xf9, 0xbc, 0x0f, 0xde, 0xc1, 0xeb, 0xcb, 0x97, 0x43, 0xf3, - 0xbc, 0xdc, 0x24, 0x8b, 0x95, 0x15, 0x3d, 0x04, 0x89, 0x7e, 0x07, 0x2c, - 0xd6, 0x9e, 0xd1, 0x28, 0xa8, 0xb0, 0x1b, 0xa0, 0xc0, 0x70, 0xff, 0x31, - 0x27, 0x91, 0x33, 0x02, 0x85, 0x77, 0x20, 0xe3, 0x18, 0x81, 0x43, 0x56, - 0x17, 0xfa, 0x06, 0xe0, 0x0f, 0xb2, 0x07, 0x92, 0x07, 0xa6, 0x90, 0xe8, - 0xcd, 0xc7, 0x46, 0x7d, 0xf8, 0xd4, 0x68, 0x98, 0x80, 0xb1, 0x1c, 0x0f, - 0xf2, 0x61, 0x1f, 0x92, 0xba, 0x3e, 0xf7, 0xea, 0x43, 0x81, 0x27, 0x34, - 0xd9, 0x33, 0x78, 0x0f, 0x8f, 0x92, 0x82, 0x86, 0xc3, 0x0f, 0xd1, 0x62, - 0x85, 0xb6, 0x90, 0x69, 0x80, 0x4c, 0xd5, 0x11, 0xd8, 0x0b, 0x73, 0xb4, - 0x97, 0x62, 0x7f, 0x10, 0x1f, 0x61, 0x32, 0x72, 0x09, 0x32, 0x53, 0x37, - 0x45, 0x52, 0x0d, 0x5b, 0xa6, 0xba, 0x70, 0x32, 0xdd, 0xab, 0x16, 0xec, - 0x17, 0xac, 0xc4, 0x2e, 0x0b, 0x9d, 0x3e, 0xc7, 0x00, 0x22, 0xa0, 0x22, - 0x86, 0x09, 0xf0, 0xc0, 0x77, 0xea, 0xcf, 0xa1, 0x77, 0xf7, 0x89, 0x70, - 0xe3, 0x1e, 0xe8, 0xc0, 0x71, 0x63, 0x45, 0xb9, 0x3e, 0x34, 0x64, 0xe7, - 0x9b, 0x55, 0x18, 0x21, 0x7f, 0x51, 0x70, 0x51, 0xc8, 0xe1, 0xbe, 0x8a, - 0x53, 0x8f, 0x8d, 0x8e, 0x25, 0xd6, 0x33, 0x03, 0x0e, 0x96, 0x35, 0x0c, - 0xb5, 0xf9, 0x3d, 0x18, 0x8c, 0xd8, 0xbb, 0x1d, 0x4e, 0xec, 0x7a, 0xfd, - 0x01, 0x4b, 0xfe, 0x8e, 0x47, 0x81, 0xf1, 0xde, 0x8d, 0x46, 0x80, 0xf5, - 0xb2, 0x67, 0x14, 0x4d, 0xc3, 0x64, 0x3e, 0x8e, 0x34, 0x52, 0xa6, 0x41, - 0x38, 0x46, 0xd9, 0x18, 0x53, 0x63, 0x04, 0x8d, 0xc1, 0x33, 0x06, 0xd1, - 0x34, 0x24, 0xa7, 0x01, 0xb8, 0x5a, 0xba, 0x7c, 0x58, 0x3a, 0x1f, 0x4b, - 0xbf, 0xc3, 0x56, 0x75, 0xad, 0xf8, 0xee, 0xff, 0xe0, 0x54, 0xeb, 0x8f, - 0xe8, 0x42, 0x57, 0xb7, 0x23, 0xea, 0x5e, 0x06, 0xae, 0x7d, 0xdd, 0xe5, - 0xb0, 0x75, 0x0f, 0x02, 0xd7, 0xe3, 0xdd, 0x7e, 0xc4, 0xa1, 0xe0, 0xf0, - 0x7d, 0x05, 0xe3, 0xeb, 0x82, 0xdd, 0x88, 0xaa, 0xb6, 0xc3, 0xd6, 0xa1, - 0x65, 0x30, 0xe5, 0xe7, 0x9f, 0x76, 0xf5, 0x47, 0x2c, 0xfa, 0x91, 0xc6, - 0xfc, 0x29, 0x6e, 0xa8, 0x6a, 0x82, 0xfa, 0x36, 0x9b, 0xbe, 0x7d, 0x88, - 0x00, 0x12, 0xef, 0xba, 0x82, 0xd5, 0xea, 0x5b, 0x2e, 0xea, 0xe2, 0xba, - 0x01, 0xef, 0x96, 0xe6, 0x19, 0xe6, 0x98, 0x30, 0x74, 0x7e, 0x0c, 0x02, - 0xe5, 0x26, 0x00, 0xb4, 0x69, 0xdc, 0xc6, 0xc1, 0x5e, 0x25, 0xae, 0x50, - 0xc6, 0x2f, 0x5a, 0x8d, 0x2a, 0xcb, 0xed, 0x3a, 0xc3, 0x6a, 0x49, 0x98, - 0xbc, 0x14, 0xc0, 0xa1, 0x4e, 0x2d, 0x17, 0x26, 0xa3, 0x97, 0x9e, 0x5e, - 0xad, 0x7b, 0x78, 0x2c, 0x30, 0x87, 0xe2, 0x77, 0x05, 0x16, 0x51, 0x9d, - 0x5d, 0x4b, 0x43, 0xb8, 0x94, 0xb0, 0x50, 0x6d, 0x5b, 0xcc, 0x4b, 0x70, - 0x8f, 0x40, 0x97, 0xf4, 0xd7, 0x5d, 0x38, 0x6d, 0x17, 0x48, 0x4b, 0x54, - 0x12, 0x54, 0x1a, 0xba, 0xaf, 0x64, 0xdf, 0xe7, 0x70, 0x9b, 0x35, 0x0a, - 0x0d, 0x57, 0x7a, 0x33, 0xc0, 0xf0, 0xc1, 0x03, 0x81, 0x7d, 0x67, 0x6c, - 0x0e, 0xe6, 0x0b, 0x46, 0x0e, 0xc4, 0x35, 0x6b, 0x24, 0x0f, 0x53, 0x1e, - 0xb9, 0xe5, 0xfa, 0x95, 0x6c, 0x46, 0x5e, 0x05, 0xcc, 0xa0, 0x7d, 0x16, - 0xb7, 0x51, 0x8e, 0x35, 0x05, 0x13, 0x58, 0x0c, 0xdc, 0x8e, 0xfd, 0x0f, - 0x2e, 0x2c, 0xcf, 0xb8, 0xab, 0xe5, 0x68, 0xb7, 0x82, 0x35, 0x4b, 0x6c, - 0x0c, 0x80, 0x64, 0x1d, 0x41, 0x1d, 0x4c, 0xd5, 0xf7, 0x3a, 0xf2, 0xe3, - 0xe5, 0xa1, 0x00, 0x07, 0xce, 0xd7, 0x4a, 0xb8, 0xcf, 0xca, 0xe0, 0xb4, - 0xf9, 0x08, 0xe0, 0x6b, 0x40, 0xbf, 0xbe, 0x73, 0xb0, 0x33, 0x74, 0xa8, - 0x88, 0x63, 0xc8, 0x05, 0x0e, 0xeb, 0x73, 0x71, 0x9b, 0xec, 0x8e, 0x03, - 0xbe, 0x62, 0x3f, 0xc0, 0x9a, 0xc9, 0x0a, 0x1d, 0xdb, 0x05, 0x17, 0x8a, - 0x1a, 0x30, 0x3e, 0xcb, 0xde, 0x97, 0xe6, 0x80, 0xc5, 0x3e, 0xab, 0xe0, - 0xd6, 0x0c, 0x09, 0x03, 0xaa, 0xc4, 0xc4, 0x3a, 0xda, 0x11, 0x49, 0x38, - 0x46, 0xfb, 0xb8, 0x1b, 0x6d, 0x39, 0x1f, 0xed, 0xa9, 0x72, 0x9c, 0x0f, - 0x7c, 0x37, 0xda, 0x81, 0xa3, 0x5d, 0xbc, 0x33, 0x5a, 0x54, 0xd0, 0xe2, - 0xcf, 0xf2, 0x2f, 0x1d, 0xff, 0x4e, 0x6b, 0x3d, 0xcd, 0xff, 0x23, 0x7f, - 0xa8, 0x1d, 0xe6, 0xe4, 0xb7, 0x46, 0xe0, 0xdf, 0x28, 0x11, 0x84, 0xc9, - 0xee, 0xab, 0xfd, 0xed, 0x7d, 0xdc, 0xaf, 0xff, 0xf6, 0x68, 0x7f, 0xf7, - 0x68, 0x30, 0x2b, 0x2c, 0xe2, 0x96, 0x34, 0xee, 0xe4, 0x00, 0xa4, 0xc3, - 0x44, 0x58, 0xda, 0x86, 0xca, 0x33, 0x49, 0x37, 0x69, 0x4f, 0x89, 0xdd, - 0xd4, 0x6b, 0x06, 0xda, 0x61, 0xbf, 0xa8, 0x50, 0xd9, 0x99, 0x30, 0xe9, - 0x47, 0x79, 0x6c, 0xdc, 0x3d, 0x4e, 0xc5, 0xb8, 0x1b, 0x92, 0x41, 0x65, - 0x92, 0x0c, 0x6b, 0x90, 0x97, 0x82, 0xea, 0xd2, 0x59, 0x79, 0xa5, 0x1f, - 0xef, 0x5e, 0x8a, 0x9f, 0x17, 0x09, 0xcf, 0x55, 0x1a, 0x5b, 0x92, 0xf2, - 0x53, 0x65, 0xfb, 0xc1, 0xcb, 0x7a, 0x9c, 0x06, 0xe4, 0x3f, 0x38, 0x4e, - 0xf7, 0xae, 0xf7, 0x71, 0xea, 0x6f, 0x6c, 0x71, 0xbf, 0x7b, 0xb3, 0xe4, - 0x94, 0xdc, 0xbe, 0xc8, 0x43, 0x09, 0xab, 0xd2, 0x76, 0x67, 0x9b, 0x0e, - 0x89, 0x8a, 0xfe, 0x66, 0xa7, 0xe9, 0xf8, 0x80, 0x8e, 0x20, 0xf7, 0xb3, - 0xa0, 0xe7, 0x20, 0xe2, 0xa8, 0x17, 0x42, 0xba, 0xce, 0xa8, 0x95, 0xfb, - 0x2b, 0xba, 0x17, 0xbc, 0xdf, 0x80, 0xda, 0x6f, 0xee, 0x42, 0x8b, 0x6f, - 0x3b, 0x59, 0x80, 0xc1, 0x25, 0x7f, 0x97, 0x61, 0x60, 0xf1, 0x86, 0x6e, - 0xb6, 0xd7, 0x4b, 0x86, 0x42, 0x41, 0xd2, 0x50, 0x15, 0xb0, 0x09, 0x6a, - 0x6e, 0xeb, 0x9e, 0xc7, 0xb7, 0x25, 0xf2, 0xea, 0x30, 0x4d, 0xf7, 0xc9, - 0x3e, 0x16, 0x78, 0x1a, 0x21, 0x71, 0xc7, 0xf4, 0xb6, 0x1c, 0x9f, 0x4d, - 0x84, 0x32, 0xa7, 0xf4, 0x81, 0x37, 0x64, 0x05, 0xff, 0xee, 0x8b, 0x24, - 0xf0, 0x6f, 0xe4, 0x61, 0x43, 0xd7, 0x91, 0xc7, 0x94, 0x7e, 0xe3, 0x4f, - 0x51, 0x22, 0x5e, 0xa6, 0x1d, 0x58, 0x9c, 0x42, 0xe3, 0x82, 0xd0, 0xf8, - 0x47, 0xea, 0xd9, 0x83, 0x85, 0x1c, 0xc1, 0x02, 0x0f, 0xfb, 0x0a, 0x16, - 0x82, 0xb9, 0x62, 0xde, 0x5a, 0x51, 0x79, 0x91, 0xe4, 0xf6, 0x04, 0xac, - 0xbf, 0x81, 0x74, 0x35, 0xfb, 0xa4, 0x34, 0xe1, 0x32, 0x87, 0x05, 0x23, - 0x97, 0x80, 0xd0, 0x2c, 0x01, 0x66, 0x69, 0x32, 0xfc, 0xe5, 0x43, 0xdc, - 0x35, 0x76, 0x35, 0x84, 0x87, 0xa7, 0x1d, 0x19, 0xa2, 0x1b, 0xf0, 0x43, - 0x52, 0x03, 0x22, 0xec, 0x98, 0x95, 0x7f, 0xa6, 0x79, 0xf9, 0xe5, 0x43, - 0x20, 0x80, 0x5c, 0x6f, 0x30, 0xee, 0x07, 0xbe, 0xc2, 0x63, 0x05, 0x0b, - 0x16, 0xc1, 0x1a, 0x7b, 0x38, 0x0b, 0x99, 0x7b, 0x38, 0x28, 0x05, 0x4f, - 0xf3, 0x9b, 0x19, 0x4a, 0xea, 0xa8, 0x15, 0x41, 0xee, 0x30, 0x84, 0xf5, - 0xb6, 0x58, 0x90, 0xf3, 0x30, 0x7a, 0x1a, 0x3e, 0xb9, 0xf4, 0x3b, 0xf7, - 0xe6, 0x49, 0x20, 0xc9, 0x10, 0x62, 0xbb, 0xbb, 0x34, 0xdc, 0xe3, 0x53, - 0xea, 0xd0, 0x77, 0xf2, 0x2b, 0x68, 0x81, 0x5b, 0x74, 0xa5, 0xb4, 0x1b, - 0x58, 0x7a, 0x86, 0x07, 0xee, 0x38, 0xa4, 0xe8, 0xb2, 0xf9, 0x0b, 0x58, - 0x1d, 0xa9, 0xb9, 0x72, 0x74, 0x90, 0xf5, 0x48, 0x8a, 0x6e, 0x4f, 0x76, - 0xcb, 0x4b, 0xcd, 0x78, 0x53, 0xe2, 0xbd, 0x8c, 0xa0, 0x2e, 0x82, 0xc5, - 0xd2, 0x81, 0x33, 0xe0, 0xd3, 0x4f, 0xd2, 0x54, 0x5e, 0xce, 0x74, 0xa3, - 0x82, 0xc7, 0x02, 0xd8, 0x8a, 0x65, 0x61, 0xd3, 0x7f, 0xa9, 0x35, 0xda, - 0x95, 0x84, 0x91, 0xdb, 0x0e, 0xf0, 0x7d, 0xc2, 0x74, 0x59, 0x02, 0x5d, - 0x1c, 0x38, 0x38, 0x76, 0x49, 0x46, 0x42, 0xaa, 0x04, 0xb7, 0x06, 0x4e, - 0x0d, 0x5c, 0x1a, 0xf8, 0x38, 0xcd, 0x13, 0x3f, 0xbe, 0xf1, 0xe8, 0x3d, - 0xdd, 0x18, 0x78, 0xd0, 0x70, 0x0e, 0x02, 0x7c, 0x15, 0x5c, 0xd2, 0x5d, - 0xf0, 0x47, 0xe9, 0xf1, 0x6b, 0x9f, 0xf1, 0xee, 0x17, 0xea, 0x2f, 0xec, - 0x7e, 0x63, 0x6f, 0xf3, 0xf9, 0xef, 0x26, 0x17, 0xfc, 0x06, 0x3f, 0xbd, - 0x1c, 0xdc, 0xeb, 0xdf, 0xff, 0xfc, 0x23, 0xbb, 0xf2, 0x8f, 0x6c, 0x8b, - 0x3f, 0xff, 0xc1, 0x39, 0xc5, 0x8f, 0x5b, 0x99, 0xa9, 0xdd, 0xff, 0x32, - 0x7f, 0x54, 0x00, 0x38, 0x93, 0x99, 0x1f, 0x67, 0x71, 0x67, 0xa9, 0xc0, - 0xb7, 0xc3, 0x18, 0xe0, 0xc9, 0x61, 0x44, 0x79, 0x0c, 0x1f, 0xc8, 0x3e, - 0xf1, 0x6b, 0x00, 0xc7, 0x30, 0x8c, 0xc6, 0xd1, 0x72, 0x9d, 0xf6, 0xba, - 0x5d, 0x09, 0x1f, 0x88, 0x23, 0x19, 0xb8, 0x91, 0x26, 0x4a, 0x0b, 0x51, - 0x74, 0xd1, 0xfb, 0xdb, 0x38, 0x26, 0x0f, 0x99, 0x64, 0xb8, 0xa8, 0xe2, - 0x80, 0xbb, 0x57, 0xa5, 0xc0, 0x2b, 0xa5, 0x17, 0x03, 0x37, 0x98, 0xb4, - 0x0b, 0x96, 0xd5, 0x93, 0x5c, 0x6a, 0x9a, 0x0d, 0xee, 0x90, 0xee, 0x06, - 0xbb, 0xca, 0x87, 0xd4, 0xae, 0x52, 0xbb, 0xd9, 0xa5, 0x86, 0x09, 0x76, - 0x15, 0xbe, 0x4d, 0x4d, 0xfb, 0x4f, 0x45, 0xb4, 0x37, 0xfb, 0xcf, 0x53, - 0x6a, 0xd2, 0x0d, 0x40, 0xa1, 0x3b, 0xe6, 0xf4, 0xab, 0x3f, 0xa7, 0x7e, - 0x85, 0xc3, 0xd2, 0xc5, 0xaa, 0xda, 0xd0, 0x5d, 0xe1, 0x45, 0x52, 0xdd, - 0xe7, 0x52, 0xa0, 0x1c, 0xce, 0x2f, 0xc5, 0x9c, 0x5d, 0x72, 0x9b, 0x8d, - 0x97, 0xa7, 0x47, 0xc2, 0xc4, 0x41, 0xb2, 0x00, 0xf4, 0xa5, 0xb4, 0xdf, - 0xf1, 0x51, 0x0f, 0x8c, 0x92, 0x16, 0xc3, 0xe2, 0x0c, 0xfc, 0xeb, 0x20, - 0x8a, 0x6f, 0x7c, 0xf2, 0x83, 0xbf, 0x06, 0x70, 0xd0, 0xa2, 0xa1, 0x26, - 0xff, 0x61, 0xa3, 0x23, 0x94, 0x77, 0xa4, 0x0b, 0x8d, 0x95, 0xa9, 0xd4, - 0xa7, 0x7d, 0xff, 0x2f, 0xef, 0xff, 0x1a, 0x10, 0x5f, 0x2e, 0x31, 0x36, - 0xdd, 0x94, 0x43, 0xfe, 0x07, 0xef, 0xb2, 0x66, 0x87, 0x36, 0xd0, 0x52, - 0x8f, 0xf6, 0xe8, 0xd3, 0xf8, 0xfe, 0xaf, 0x92, 0xea, 0x57, 0x4f, 0xb0, - 0x76, 0xff, 0xb2, 0xe5, 0x17, 0x7e, 0x60, 0xd4, 0xd7, 0x8f, 0x70, 0xe8, - 0xc9, 0x41, 0x67, 0x34, 0xae, 0x07, 0xd5, 0x02, 0x5e, 0x2d, 0xd1, 0x52, - 0x53, 0x2c, 0xbd, 0x61, 0x88, 0x9a, 0x3b, 0x9c, 0x98, 0x19, 0x2a, 0x6a, - 0x88, 0xee, 0x11, 0xb7, 0xf7, 0xa0, 0x5c, 0xdc, 0xb9, 0xa5, 0x3b, 0xaa, - 0x9e, 0x2d, 0x63, 0xe7, 0x91, 0xc1, 0x29, 0xba, 0xa6, 0xf4, 0x4b, 0xbf, - 0xf5, 0xf4, 0xb4, 0x2a, 0xd6, 0x9c, 0x43, 0x6d, 0x68, 0x52, 0x46, 0x68, - 0xd7, 0x32, 0x70, 0x01, 0x63, 0x48, 0x33, 0xa5, 0x11, 0xc2, 0x56, 0xc3, - 0x37, 0x35, 0x72, 0xa2, 0xc4, 0x8e, 0x5f, 0x9f, 0xea, 0x97, 0x4d, 0x40, - 0x48, 0x24, 0x8d, 0x40, 0x27, 0x4d, 0xfd, 0x18, 0x53, 0xbb, 0x4f, 0xe6, - 0xbd, 0x24, 0x04, 0x99, 0xb3, 0xf4, 0x41, 0xe1, 0x57, 0xc9, 0xf3, 0xab, - 0xc6, 0xf3, 0x64, 0x34, 0x36, 0xb9, 0x8f, 0x25, 0x45, 0x0d, 0x01, 0xd4, - 0x68, 0xc6, 0xa0, 0xd1, 0x23, 0xc6, 0x20, 0xa1, 0x40, 0x35, 0x6c, 0xa4, - 0x1f, 0x66, 0x6a, 0xbc, 0xa8, 0xdd, 0xd6, 0x78, 0xd1, 0x0b, 0xa4, 0xb4, - 0x88, 0x23, 0x39, 0x0f, 0x14, 0x1d, 0x23, 0x44, 0xf0, 0xc8, 0x35, 0xd2, - 0xd5, 0x9f, 0x9c, 0x9a, 0xb3, 0xe0, 0xea, 0x47, 0xcf, 0x8e, 0xa7, 0xff, - 0x05, 0xbc, 0x47, 0xa4, 0x19, 0x06, 0x2d, 0x00, 0x00 -}; - -const GFXglyph Oswald_Medium30pt7bGlyphs[] PROGMEM = { - { 0, 1, 1, 14, 0, 0 }, // 0x20 ' ' - { 1, 8, 48, 14, 3, -47 }, // 0x21 '!' - { 49, 17, 17, 19, 1, -47 }, // 0x22 '"' - { 86, 26, 48, 30, 2, -47 }, // 0x23 '#' - { 242, 25, 59, 29, 2, -52 }, // 0x24 '$' - { 427, 51, 48, 56, 2, -47 }, // 0x25 '%' - { 733, 29, 49, 34, 3, -47 }, // 0x26 '&' - { 911, 7, 17, 9, 1, -47 }, // 0x27 ''' - { 926, 13, 59, 19, 4, -47 }, // 0x28 '(' - { 1022, 13, 59, 17, 2, -47 }, // 0x29 ')' - { 1118, 21, 21, 24, 2, -47 }, // 0x2A '*' - { 1174, 22, 24, 25, 2, -35 }, // 0x2B '+' - { 1240, 8, 16, 13, 2, -7 }, // 0x2C ',' - { 1256, 14, 6, 18, 2, -19 }, // 0x2D '-' - { 1267, 8, 8, 13, 3, -7 }, // 0x2E '.' - { 1275, 19, 48, 23, 2, -47 }, // 0x2F '/' - { 1389, 25, 49, 31, 3, -47 }, // 0x30 '0' - { 1543, 15, 48, 22, 2, -47 }, // 0x31 '1' - { 1633, 25, 48, 29, 2, -47 }, // 0x32 '2' - { 1783, 25, 49, 29, 2, -47 }, // 0x33 '3' - { 1937, 27, 48, 30, 2, -47 }, // 0x34 '4' - { 2099, 24, 49, 29, 3, -47 }, // 0x35 '5' - { 2246, 25, 49, 31, 3, -47 }, // 0x36 '6' - { 2400, 21, 48, 24, 1, -47 }, // 0x37 '7' - { 2526, 24, 49, 30, 3, -47 }, // 0x38 '8' - { 2673, 25, 49, 31, 2, -47 }, // 0x39 '9' - { 2827, 7, 28, 14, 4, -31 }, // 0x3A ':' - { 2852, 8, 38, 15, 4, -32 }, // 0x3B ';' - { 2890, 18, 25, 23, 2, -36 }, // 0x3C '<' - { 2947, 19, 16, 25, 3, -31 }, // 0x3D '=' - { 2985, 18, 25, 23, 3, -36 }, // 0x3E '>' - { 3042, 24, 48, 28, 2, -47 }, // 0x3F '?' - { 3186, 50, 56, 55, 3, -47 }, // 0x40 '@' - { 3536, 29, 48, 31, 1, -47 }, // 0x41 'A' - { 3710, 27, 48, 33, 4, -47 }, // 0x42 'B' - { 3872, 26, 49, 32, 3, -47 }, // 0x43 'C' - { 4032, 26, 48, 33, 4, -47 }, // 0x44 'D' - { 4188, 20, 48, 25, 4, -47 }, // 0x45 'E' - { 4308, 19, 48, 24, 4, -47 }, // 0x46 'F' - { 4422, 27, 49, 33, 3, -47 }, // 0x47 'G' - { 4588, 27, 48, 34, 4, -47 }, // 0x48 'H' - { 4750, 8, 48, 16, 4, -47 }, // 0x49 'I' - { 4798, 15, 49, 19, 1, -47 }, // 0x4A 'J' - { 4890, 27, 48, 31, 4, -47 }, // 0x4B 'K' - { 5052, 20, 48, 25, 4, -47 }, // 0x4C 'L' - { 5172, 34, 48, 40, 3, -47 }, // 0x4D 'M' - { 5376, 24, 48, 32, 4, -47 }, // 0x4E 'N' - { 5520, 27, 49, 33, 3, -47 }, // 0x4F 'O' - { 5686, 26, 48, 31, 4, -47 }, // 0x50 'P' - { 5842, 27, 57, 33, 3, -47 }, // 0x51 'Q' - { 6035, 27, 48, 33, 4, -47 }, // 0x52 'R' - { 6197, 26, 49, 29, 2, -47 }, // 0x53 'S' - { 6357, 24, 48, 25, 1, -47 }, // 0x54 'T' - { 6501, 27, 49, 33, 3, -47 }, // 0x55 'U' - { 6667, 28, 48, 30, 1, -47 }, // 0x56 'V' - { 6835, 38, 48, 42, 2, -47 }, // 0x57 'W' - { 7063, 28, 48, 29, 1, -47 }, // 0x58 'X' - { 7231, 27, 48, 29, 1, -47 }, // 0x59 'Y' - { 7393, 22, 48, 25, 2, -47 }, // 0x5A 'Z' - // Euro sign ([) - ASCII code 91 - { 11030, 30, 49, 31, 0, -47 }, // 0x5B '[' - // Backslash placeholder - ASCII code 92 - { 0, 0, 0, 0, 0, 0 }, // 0x5C '\' - // Pound sign (]) - ASCII code 93 - { 11214, 24, 48, 26, 1, -47 }, // 0x5D ']' - // Yen sign (^) - ASCII code 94 - { 11358, 28, 48, 27, 0, -47 }, // 0x5E '^' - { 7905, 21, 6, 21, 0, 4 }, // 0x5F '_' - { 7921, 11, 12, 17, 3, -47 }, // 0x60 '`' - { 7938, 22, 35, 26, 1, -33 }, // 0x61 'a' - { 8035, 23, 49, 28, 3, -47 }, // 0x62 'b' - { 8176, 22, 35, 26, 2, -33 }, // 0x63 'c' - { 8273, 23, 49, 28, 2, -47 }, // 0x64 'd' - { 8414, 22, 35, 26, 2, -33 }, // 0x65 'e' - { 8511, 16, 46, 18, 1, -45 }, // 0x66 'f' - { 8603, 28, 46, 28, 1, -34 }, // 0x67 'g' - { 8764, 22, 48, 28, 3, -47 }, // 0x68 'h' - { 8896, 8, 46, 15, 3, -45 }, // 0x69 'i' - { 8942, 13, 56, 15, -1, -45 }, // 0x6A 'j' - { 9033, 25, 48, 28, 3, -47 }, // 0x6B 'k' - { 9183, 8, 48, 15, 4, -47 }, // 0x6C 'l' - { 9231, 36, 35, 42, 3, -34 }, // 0x6D 'm' - { 9389, 22, 34, 28, 3, -33 }, // 0x6E 'n' - { 9483, 22, 35, 27, 2, -33 }, // 0x6F 'o' - { 9580, 23, 45, 28, 3, -33 }, // 0x70 'p' - { 9710, 22, 45, 28, 3, -33 }, // 0x71 'q' - { 9834, 17, 34, 21, 3, -33 }, // 0x72 'r' - { 9907, 21, 35, 24, 1, -33 }, // 0x73 's' - { 9999, 17, 44, 19, 1, -43 }, // 0x74 't' - { 10093, 22, 35, 28, 3, -33 }, // 0x75 'u' - { 10190, 22, 34, 24, 1, -33 }, // 0x76 'v' - { 10284, 32, 34, 35, 1, -33 }, // 0x77 'w' - { 10420, 23, 34, 24, 1, -33 }, // 0x78 'x' - { 10518, 24, 43, 25, 0, -33 }, // 0x79 'y' - { 10647, 18, 34, 22, 2, -33 }, // 0x7A 'z' - { 10724, 15, 59, 20, 3, -47 }, // 0x7B '{' - { 10835, 7, 58, 15, 4, -47 }, // 0x7C '|' - { 10886, 16, 59, 21, 2, -47 }, // 0x7D '}' - { 11004, 23, 9, 27, 2, -28 } }; // 0x7E '~' - -// const GFXfont Oswald_Medium30pt7b PROGMEM = { -// (uint8_t *)Oswald_Medium30pt7bBitmaps, -// (GFXglyph *)Oswald_Medium30pt7bGlyphs, -// 0x20, 0x7E, 87 }; - -// Approx. 11702 bytes - - -// Font properties -static constexpr FontData Oswald_Medium30pt7b_Properties = { - Oswald_Medium30pt7bBitmaps_Gzip, - Oswald_Medium30pt7bGlyphs, - sizeof(Oswald_Medium30pt7bBitmaps_Gzip), - 11526, // Original size - 0x20, // First char - 0x7E, // Last char - 87 // yAdvance -}; diff --git a/src/fonts/oswald-medium80.h b/src/fonts/oswald-medium80.h deleted file mode 100644 index dfab628..0000000 --- a/src/fonts/oswald-medium80.h +++ /dev/null @@ -1,1083 +0,0 @@ -#pragma once - -#include -#include -#include "fonts.hpp" - -const uint8_t Oswald_Medium80pt7bBitmaps_Gzip[] = { - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xed, 0x7d, - 0x4d, 0xae, 0xdc, 0x38, 0xb3, 0xa5, 0xf4, 0xd4, 0x80, 0xde, 0xa0, 0xd1, - 0xea, 0x05, 0x34, 0x9a, 0xbd, 0x84, 0x5e, 0x40, 0xe3, 0xb1, 0x97, 0xf5, - 0x06, 0x0d, 0x50, 0x05, 0x0f, 0x3c, 0xac, 0x25, 0x78, 0x29, 0x56, 0xc1, - 0x83, 0x1a, 0x7a, 0x09, 0xa6, 0x51, 0x03, 0x0f, 0x2d, 0xc3, 0x83, 0x92, - 0x61, 0x95, 0xd8, 0x8a, 0x88, 0x73, 0x82, 0x4a, 0x65, 0xa6, 0x7d, 0x7d, - 0xcb, 0xe5, 0xfa, 0xf9, 0x9c, 0xa8, 0xba, 0xa2, 0x23, 0xc9, 0x10, 0x19, - 0x8c, 0x08, 0xc6, 0x9f, 0x94, 0x4d, 0xb9, 0xf1, 0xd9, 0x4a, 0xf9, 0xb5, - 0x94, 0xe7, 0xe5, 0xb7, 0x52, 0xde, 0x96, 0x12, 0xcb, 0x87, 0x52, 0x5e, - 0x96, 0x2d, 0x95, 0xf7, 0xa5, 0x3c, 0x2b, 0x6b, 0x29, 0x6f, 0xca, 0x16, - 0xcb, 0xbb, 0x52, 0x7e, 0x2c, 0x6b, 0x2a, 0xbf, 0x94, 0x12, 0xca, 0x52, - 0xca, 0x8b, 0xb2, 0x85, 0x32, 0x97, 0xf2, 0xb4, 0xac, 0xb1, 0xbc, 0x2e, - 0xdb, 0x50, 0xe6, 0x54, 0x9e, 0x94, 0x35, 0x94, 0x5c, 0x4a, 0x5f, 0x96, - 0x58, 0x7e, 0x52, 0x60, 0x2c, 0x3f, 0x94, 0x75, 0x28, 0x53, 0xda, 0xba, - 0x32, 0x87, 0x32, 0x96, 0xb5, 0x2f, 0x39, 0x96, 0xb6, 0x2c, 0x17, 0xc0, - 0xae, 0x4c, 0x61, 0x6b, 0xca, 0xdc, 0x97, 0x31, 0xae, 0x6d, 0xc9, 0x43, - 0x69, 0xd2, 0x72, 0x02, 0x4e, 0xc3, 0xd6, 0xc4, 0xb9, 0x2d, 0xe3, 0xb0, - 0x36, 0x29, 0x77, 0xa5, 0x09, 0x4b, 0x53, 0xa6, 0xfe, 0x00, 0x9c, 0xba, - 0xad, 0x09, 0x73, 0x53, 0xc6, 0x6e, 0x6d, 0x42, 0x6e, 0x4a, 0xd3, 0x2f, - 0x4d, 0x9c, 0xda, 0xad, 0x19, 0xe6, 0x26, 0x09, 0xf0, 0xce, 0x27, 0x62, - 0xed, 0xa9, 0x7c, 0x2c, 0xe5, 0xd5, 0x89, 0x20, 0xf7, 0x81, 0xd3, 0xfe, - 0x5f, 0xda, 0x09, 0xb8, 0x2f, 0x65, 0xff, 0xb4, 0xf2, 0x67, 0x8a, 0xf2, - 0xef, 0x5e, 0x9a, 0x8d, 0xf4, 0xce, 0x61, 0x1f, 0xb5, 0xaf, 0x6e, 0x1f, - 0x3d, 0xa6, 0x1d, 0xcb, 0xbe, 0xb0, 0x8f, 0x65, 0x5f, 0xcb, 0x8e, 0x60, - 0x8c, 0x3b, 0x99, 0xf7, 0xb5, 0x7d, 0x28, 0xfb, 0x1a, 0x77, 0xb2, 0x8f, - 0x61, 0xa7, 0xf4, 0xdc, 0xed, 0x14, 0xdf, 0x9a, 0xb4, 0x13, 0x79, 0x1a, - 0x76, 0x62, 0x2f, 0xed, 0x4e, 0xf4, 0x7d, 0x85, 0x3b, 0xf1, 0xa7, 0x7e, - 0xdf, 0x84, 0x7d, 0xc5, 0xfb, 0x66, 0x34, 0x61, 0xa7, 0xfb, 0x4e, 0x81, - 0x79, 0xff, 0x77, 0xda, 0xf7, 0xa1, 0x19, 0xf6, 0xfd, 0xc8, 0x3b, 0x4d, - 0xd3, 0xda, 0xc4, 0x9d, 0xea, 0x63, 0xbf, 0x53, 0x7f, 0xa7, 0xc3, 0x12, - 0x77, 0x3a, 0xec, 0xbb, 0x31, 0x76, 0xfb, 0xae, 0xec, 0x24, 0x58, 0x76, - 0x72, 0x0e, 0x65, 0x27, 0xeb, 0x4e, 0xe1, 0x34, 0x37, 0x71, 0xdd, 0x29, - 0xda, 0xef, 0x1b, 0x34, 0xed, 0x44, 0x8e, 0x4b, 0x13, 0xf6, 0xbd, 0x69, - 0xba, 0x7d, 0x3b, 0xa6, 0x26, 0xcd, 0x3b, 0x71, 0x87, 0x7d, 0x7b, 0x9a, - 0x9d, 0xee, 0x3b, 0x85, 0x82, 0x0c, 0xdf, 0x5b, 0xfb, 0xcc, 0xf7, 0x11, - 0x0b, 0x01, 0xe3, 0x11, 0x90, 0x01, 0x90, 0x7b, 0x00, 0xb0, 0xaf, 0x7a, - 0x47, 0x08, 0x40, 0x54, 0x40, 0x03, 0xc0, 0x7c, 0x13, 0x30, 0xb5, 0x06, - 0x58, 0xf5, 0x06, 0x0e, 0xe8, 0x09, 0x48, 0x02, 0xd8, 0x08, 0xc8, 0x47, - 0xc0, 0x42, 0xc0, 0xd8, 0x11, 0x20, 0x37, 0x90, 0x39, 0x28, 0x60, 0x50, - 0xc0, 0x04, 0xc0, 0x7a, 0x13, 0x60, 0x8b, 0x6c, 0x74, 0x4d, 0x07, 0x40, - 0x4b, 0xc0, 0x8d, 0x55, 0xdf, 0x20, 0x43, 0xb9, 0x41, 0x86, 0x04, 0x61, - 0xfb, 0x95, 0x52, 0xf7, 0x6d, 0x00, 0x8f, 0x5f, 0xe4, 0xe7, 0xf6, 0xfa, - 0xd6, 0x22, 0xcf, 0x7b, 0x3d, 0x5e, 0xed, 0xf5, 0x50, 0x75, 0x8e, 0x7d, - 0xde, 0x7e, 0x13, 0x40, 0x3e, 0x90, 0xe1, 0x72, 0xd5, 0xcd, 0x97, 0xac, - 0x7a, 0x7e, 0xe4, 0xaa, 0xbf, 0x12, 0x87, 0xaf, 0xc6, 0xd0, 0x57, 0x1c, - 0x9e, 0x2e, 0x38, 0x3c, 0x7f, 0x92, 0xc3, 0x97, 0xdb, 0x9b, 0xff, 0x30, - 0x32, 0x0c, 0x5f, 0x42, 0x06, 0x53, 0xad, 0xdd, 0x02, 0x1d, 0x9b, 0x70, - 0x1d, 0xb2, 0x5d, 0x5b, 0x6a, 0xe3, 0x38, 0xda, 0xb5, 0x9f, 0x01, 0xd8, - 0x70, 0x0d, 0xd3, 0x17, 0xa2, 0xd8, 0xa7, 0xa8, 0x43, 0xba, 0x62, 0x77, - 0x97, 0xeb, 0x6a, 0x70, 0xfb, 0x46, 0x79, 0x42, 0xf5, 0xbd, 0xf0, 0x84, - 0xcc, 0xdc, 0x00, 0xbd, 0x31, 0x89, 0x75, 0x14, 0x40, 0x02, 0x20, 0x00, - 0xd0, 0x19, 0x1b, 0x4d, 0x8d, 0x5d, 0x57, 0xc3, 0x50, 0x44, 0xd1, 0xea, - 0x67, 0x69, 0x29, 0x6f, 0xf8, 0x62, 0xde, 0x19, 0x7d, 0x6b, 0xf1, 0xbf, - 0x70, 0x7d, 0x4e, 0x42, 0xa2, 0x22, 0x67, 0xe1, 0x8e, 0x77, 0xff, 0xf3, - 0xc3, 0x3e, 0x4a, 0x6e, 0xb8, 0x9f, 0x94, 0x45, 0x67, 0x32, 0x08, 0xfe, - 0xfd, 0x46, 0xaf, 0x8b, 0xd1, 0x70, 0x8d, 0xc6, 0x17, 0xbb, 0xaa, 0xb7, - 0x3d, 0x5d, 0x8a, 0xed, 0xd8, 0x7e, 0x36, 0x14, 0x5d, 0xd4, 0x7e, 0x16, - 0x2b, 0x07, 0xed, 0xc7, 0xb2, 0x2d, 0xe2, 0xc7, 0x62, 0x5b, 0xf9, 0xae, - 0xd8, 0xbe, 0x6c, 0xd1, 0x78, 0xad, 0xfc, 0x5c, 0x8c, 0x4f, 0xb2, 0xa2, - 0xe8, 0xe5, 0xac, 0x91, 0x9e, 0xab, 0x7c, 0xb7, 0xf7, 0xfc, 0x5f, 0xba, - 0x62, 0x25, 0x62, 0xaf, 0x38, 0x8d, 0x56, 0xb6, 0x0b, 0x00, 0x90, 0xa8, - 0xb2, 0xc2, 0x19, 0x3d, 0x0b, 0x7b, 0xea, 0x86, 0x0c, 0x46, 0x5c, 0xa5, - 0xe2, 0x8c, 0xa1, 0xbe, 0x0f, 0x33, 0x86, 0x5e, 0x02, 0x12, 0x00, 0xfd, - 0x11, 0x30, 0x02, 0xb0, 0x00, 0xb9, 0x02, 0x86, 0x07, 0x01, 0x56, 0xe2, - 0x98, 0x80, 0xe3, 0x0b, 0x00, 0x23, 0x26, 0xb6, 0x70, 0xa6, 0x9f, 0x07, - 0xdc, 0x5c, 0x6d, 0x4b, 0x7a, 0x84, 0x03, 0x3d, 0x26, 0x00, 0x56, 0x02, - 0x46, 0x00, 0x96, 0x33, 0x6d, 0x33, 0x00, 0x1b, 0x01, 0x3b, 0x53, 0xe8, - 0x4c, 0x17, 0xe5, 0x7b, 0xd9, 0xa7, 0x68, 0x6c, 0xf0, 0x4e, 0xb1, 0xa8, - 0x96, 0x9b, 0x15, 0xd7, 0x2b, 0x19, 0xb4, 0x23, 0xff, 0xa8, 0xf7, 0x8b, - 0x72, 0x1c, 0x2c, 0x3a, 0xf4, 0x2d, 0x7a, 0x16, 0xf6, 0x54, 0xf4, 0x1d, - 0x78, 0xda, 0xb8, 0x7d, 0x51, 0x9c, 0x6f, 0x4d, 0xb2, 0xc5, 0xca, 0x51, - 0xd6, 0xda, 0xed, 0x12, 0x63, 0xad, 0x37, 0x60, 0xc2, 0xb5, 0x98, 0x96, - 0x30, 0x5e, 0xeb, 0xc8, 0x6b, 0x45, 0x79, 0x6d, 0x94, 0x2f, 0x5e, 0x08, - 0x40, 0xd8, 0x48, 0xa6, 0x2a, 0xec, 0x3f, 0x14, 0xd5, 0x3a, 0x62, 0x2e, - 0xa9, 0x18, 0xcc, 0x26, 0x55, 0x2a, 0x1b, 0x26, 0x45, 0x14, 0x1a, 0x88, - 0xd9, 0x95, 0x78, 0x65, 0x08, 0xe4, 0x02, 0x49, 0x75, 0x09, 0x1d, 0x5d, - 0x74, 0x7d, 0x11, 0x3d, 0x3a, 0x18, 0x60, 0xc4, 0x32, 0x27, 0x6c, 0x50, - 0x06, 0xc7, 0xcc, 0xd8, 0x07, 0xfd, 0xf7, 0xde, 0x77, 0xb4, 0xeb, 0xef, - 0xd7, 0x41, 0x0f, 0x47, 0x11, 0x6c, 0xef, 0x9b, 0x02, 0x0c, 0xad, 0xf3, - 0x0f, 0x00, 0x3d, 0xe6, 0xdb, 0xa2, 0xa3, 0x2e, 0x60, 0x3e, 0x02, 0x52, - 0xa1, 0x82, 0x03, 0x80, 0x6b, 0xef, 0x00, 0x30, 0x0a, 0x2b, 0xc0, 0xa6, - 0xd5, 0x15, 0xa7, 0xca, 0x11, 0x30, 0xc9, 0xdd, 0x66, 0xbf, 0x2b, 0x00, - 0xb6, 0xc4, 0x81, 0x14, 0xbe, 0x0b, 0x08, 0xe4, 0xac, 0xe1, 0x1a, 0x30, - 0x11, 0xf0, 0x04, 0x2c, 0x66, 0x80, 0x5d, 0x69, 0x35, 0xc9, 0x94, 0x14, - 0x01, 0x8b, 0xfe, 0xbf, 0x03, 0x46, 0x00, 0x66, 0x23, 0xd1, 0x25, 0x60, - 0x95, 0xc6, 0x88, 0xd5, 0x3b, 0x80, 0xe4, 0x10, 0xcd, 0xfa, 0x20, 0x40, - 0xba, 0x02, 0x6c, 0x47, 0xc0, 0x76, 0x03, 0x50, 0xae, 0x00, 0x2b, 0x89, - 0x9e, 0x77, 0x52, 0x3c, 0x04, 0xd0, 0x5e, 0x03, 0x96, 0xcf, 0x00, 0xba, - 0x6b, 0xc0, 0xfc, 0x19, 0x40, 0xff, 0x00, 0x40, 0xfe, 0x0c, 0x60, 0xb8, - 0x06, 0x4c, 0x77, 0x00, 0xa4, 0x47, 0xb8, 0x06, 0x8c, 0x9f, 0x04, 0xac, - 0xd7, 0x80, 0x78, 0x0d, 0x68, 0xee, 0x02, 0x6c, 0xf7, 0xb9, 0x93, 0xce, - 0x1f, 0xdc, 0x38, 0x65, 0x27, 0xe1, 0xa0, 0x0b, 0x40, 0xbc, 0x04, 0x18, - 0x17, 0x16, 0x97, 0x55, 0xf5, 0xc5, 0x66, 0xdf, 0x38, 0xe7, 0x64, 0x07, - 0x18, 0xf3, 0xcf, 0xed, 0x09, 0x90, 0x75, 0xe3, 0x5a, 0x93, 0x8a, 0x0a, - 0x88, 0x38, 0xc2, 0x45, 0xa2, 0x3a, 0x3b, 0xef, 0xf7, 0x2e, 0x10, 0xc2, - 0x0e, 0xfa, 0x6c, 0x81, 0x98, 0x8e, 0xb2, 0x93, 0x83, 0x4a, 0x30, 0xe4, - 0x56, 0x00, 0xd1, 0x24, 0xd8, 0x24, 0xbb, 0x57, 0x63, 0x4c, 0x25, 0xd8, - 0x64, 0xbf, 0xa7, 0x6e, 0x9c, 0x74, 0xaa, 0x8b, 0x02, 0x20, 0x9f, 0x03, - 0xfe, 0xe6, 0x16, 0x8b, 0xe8, 0x74, 0xe0, 0x20, 0x53, 0x81, 0x7c, 0x26, - 0xb3, 0x28, 0x00, 0x58, 0x44, 0x1d, 0x8c, 0x0a, 0xe8, 0x09, 0x00, 0x15, - 0x00, 0xa8, 0x64, 0x19, 0xaf, 0x00, 0x83, 0x2a, 0x72, 0x57, 0x87, 0x02, - 0xd8, 0x94, 0xa0, 0x04, 0xe8, 0xfe, 0x0d, 0x47, 0x40, 0xd0, 0x15, 0x10, - 0x90, 0x8a, 0x6e, 0xd7, 0x0d, 0x80, 0xef, 0xf9, 0x76, 0x1b, 0xd0, 0x39, - 0xa0, 0x5c, 0x01, 0xd6, 0x6b, 0x40, 0x34, 0x5a, 0xd8, 0xbf, 0xdb, 0x07, - 0x00, 0x96, 0xcf, 0x00, 0xba, 0x6b, 0xc0, 0xfc, 0x19, 0x40, 0x7f, 0x0d, - 0xc8, 0x5f, 0x0a, 0x18, 0xae, 0x01, 0xd3, 0x67, 0x00, 0xe1, 0x1a, 0x30, - 0x7e, 0x06, 0x10, 0x1f, 0x00, 0x68, 0x2e, 0x89, 0x7c, 0x05, 0x48, 0x57, - 0x80, 0xed, 0x0e, 0xc0, 0xf7, 0xb6, 0x28, 0xe0, 0xc0, 0x1f, 0xd7, 0x00, - 0xe5, 0xdd, 0x03, 0x4b, 0x19, 0xa0, 0x32, 0x5d, 0x0b, 0x7b, 0xb9, 0x21, - 0x5b, 0xb6, 0x30, 0x10, 0xa6, 0x72, 0x02, 0x38, 0x27, 0x77, 0x26, 0x04, - 0x95, 0xf9, 0x6f, 0x00, 0x66, 0x9e, 0xab, 0x3c, 0x30, 0x1d, 0x90, 0x2b, - 0xa0, 0xb9, 0x00, 0x64, 0x02, 0xa6, 0x03, 0x00, 0x82, 0xcc, 0x9d, 0x6c, - 0x28, 0xea, 0xdc, 0x38, 0xd3, 0x3e, 0xdb, 0x11, 0xd0, 0x57, 0x91, 0x33, - 0x75, 0xeb, 0xd6, 0xa7, 0x9f, 0xa4, 0x89, 0x37, 0xa1, 0x76, 0x25, 0x79, - 0xaa, 0xd0, 0x10, 0x67, 0x24, 0x32, 0x5a, 0x1a, 0xb6, 0x8c, 0x11, 0xdf, - 0xd9, 0x97, 0xbd, 0xaf, 0xa3, 0x70, 0x7a, 0x81, 0xd4, 0x70, 0xe3, 0xc1, - 0xd6, 0xb2, 0xb1, 0x7b, 0x25, 0x40, 0x69, 0xa8, 0x21, 0x17, 0x12, 0x49, - 0xf0, 0x07, 0x92, 0xbc, 0x33, 0x57, 0x69, 0x92, 0x1b, 0x6e, 0xb6, 0x4f, - 0x3b, 0x68, 0x6a, 0x61, 0xd2, 0x2d, 0x36, 0xfb, 0xde, 0x7c, 0xa7, 0x6c, - 0x5a, 0x9f, 0x20, 0x3b, 0x14, 0x14, 0xd4, 0x9f, 0x41, 0x99, 0xa0, 0xed, - 0xd3, 0xa0, 0xc1, 0x41, 0x37, 0xd0, 0xc3, 0x38, 0x9e, 0xcd, 0x42, 0x10, - 0x50, 0xeb, 0xa0, 0x80, 0xa9, 0x0a, 0x68, 0x3c, 0x98, 0x2f, 0x9d, 0xea, - 0xf1, 0xd2, 0x10, 0x64, 0xbc, 0x31, 0x1a, 0x5b, 0xdb, 0x79, 0x65, 0xcc, - 0x30, 0x29, 0x52, 0x45, 0x4d, 0xe7, 0x34, 0x9b, 0x49, 0xd8, 0xab, 0x65, - 0x3c, 0x2a, 0x55, 0xb3, 0x62, 0x10, 0xac, 0x9d, 0xed, 0x5a, 0x14, 0xbb, - 0x3a, 0xdb, 0x56, 0x3d, 0xb5, 0x1d, 0xd2, 0x78, 0xec, 0x68, 0x3b, 0xf4, - 0xcc, 0xb8, 0x61, 0x10, 0x03, 0x1e, 0x9b, 0x8d, 0xdd, 0xab, 0xac, 0x13, - 0xb9, 0xc7, 0x95, 0x79, 0x82, 0xf3, 0x99, 0xf3, 0xe8, 0xe0, 0xea, 0x3f, - 0x55, 0x05, 0x44, 0x5e, 0x8b, 0xec, 0xde, 0x97, 0x6a, 0x17, 0x54, 0x2b, - 0x55, 0xb1, 0xcb, 0xa4, 0x57, 0xc7, 0xe0, 0x48, 0x55, 0x8a, 0x67, 0xbb, - 0xb5, 0xc4, 0x14, 0x42, 0x31, 0xff, 0x77, 0x36, 0xcf, 0x4a, 0x40, 0xa9, - 0x98, 0x2b, 0x31, 0x9b, 0x4b, 0xd7, 0x69, 0x2c, 0xb5, 0x98, 0xe6, 0x32, - 0x91, 0x50, 0x7a, 0x28, 0x8a, 0x28, 0x24, 0xfa, 0xa8, 0x67, 0xe5, 0xd6, - 0x8b, 0xbb, 0xa2, 0x21, 0x90, 0xa4, 0xce, 0x51, 0x27, 0xbe, 0xc7, 0x36, - 0x28, 0xd1, 0x77, 0xaf, 0x7a, 0x77, 0x7e, 0x73, 0x2f, 0x61, 0xeb, 0xb5, - 0xd7, 0x10, 0xeb, 0x4f, 0x1a, 0xbe, 0x9d, 0x7b, 0xf1, 0xb4, 0x97, 0x4e, - 0xef, 0xbb, 0xfb, 0x2e, 0xbb, 0x6b, 0xbc, 0x0c, 0xe2, 0x52, 0xcb, 0x1c, - 0x47, 0xf5, 0xbe, 0x65, 0x93, 0x86, 0xb2, 0x24, 0x0d, 0x7c, 0x64, 0x03, - 0x29, 0xa2, 0xa5, 0xa8, 0x06, 0x7e, 0x27, 0xce, 0xbb, 0x4e, 0x4a, 0x43, - 0xe2, 0x79, 0x9f, 0xfa, 0x47, 0xbd, 0xb5, 0x71, 0x7c, 0x96, 0xa9, 0xeb, - 0xb9, 0x0e, 0xd3, 0xd3, 0x22, 0xc7, 0xb6, 0x23, 0x30, 0x4f, 0xf5, 0x56, - 0x93, 0x79, 0x97, 0x03, 0x3c, 0xac, 0xd2, 0xc0, 0x9d, 0x17, 0x42, 0xac, - 0x20, 0x1e, 0x1d, 0xb6, 0x4c, 0x9e, 0x5c, 0x8d, 0x73, 0xa3, 0x72, 0x94, - 0x79, 0x75, 0x8b, 0x81, 0x82, 0x82, 0x0a, 0xbc, 0x49, 0x9c, 0xf7, 0xb2, - 0x5e, 0x35, 0x02, 0x74, 0xf1, 0x30, 0x3d, 0x74, 0x17, 0x55, 0x84, 0xa3, - 0x45, 0x2b, 0x8a, 0x04, 0xff, 0x2d, 0x8c, 0x5d, 0x62, 0xc1, 0xe7, 0x1d, - 0x1b, 0x25, 0xb0, 0x31, 0x3b, 0xc8, 0xfa, 0x7e, 0x34, 0xb7, 0xcf, 0x46, - 0x99, 0x76, 0x78, 0x4d, 0x87, 0x4f, 0x22, 0x1f, 0xa6, 0x14, 0x46, 0xa5, - 0x7a, 0x51, 0x33, 0xca, 0x18, 0x60, 0xd5, 0x40, 0x94, 0x29, 0x87, 0x54, - 0x94, 0x0c, 0x12, 0x8d, 0x99, 0xc1, 0x85, 0x43, 0x31, 0xd9, 0xd9, 0x97, - 0x29, 0x4e, 0x85, 0xc7, 0x12, 0x76, 0x77, 0xf5, 0xa3, 0xb8, 0xbf, 0xcf, - 0xb5, 0xb1, 0xca, 0x5d, 0x5f, 0xee, 0x33, 0xd7, 0xc6, 0x8f, 0x12, 0x3d, - 0x17, 0xaf, 0xf4, 0xc7, 0x7d, 0x57, 0x67, 0xd9, 0xe3, 0x41, 0x1b, 0x8b, - 0x04, 0xc8, 0x9f, 0xec, 0x9b, 0xa2, 0x8d, 0x6e, 0xdf, 0x8a, 0x39, 0xae, - 0xd6, 0xc8, 0x71, 0x91, 0x90, 0xf7, 0xa8, 0x0d, 0x65, 0x5d, 0xf1, 0xf2, - 0x82, 0x92, 0x7e, 0x54, 0xb5, 0xde, 0x99, 0xa6, 0x98, 0x54, 0xb8, 0x07, - 0xe5, 0x3a, 0xb5, 0xb7, 0xd4, 0x63, 0x15, 0x0b, 0x68, 0xd6, 0x78, 0x8f, - 0xf0, 0xfb, 0xbe, 0x2c, 0x61, 0xaa, 0x59, 0xbf, 0x0d, 0xd6, 0x75, 0xd2, - 0x5d, 0x08, 0x6a, 0xc8, 0xa9, 0x46, 0x9b, 0x71, 0xa2, 0xdd, 0xfb, 0x47, - 0x67, 0x04, 0xb1, 0x31, 0x9d, 0xed, 0x92, 0xe9, 0xc4, 0xf6, 0x38, 0x8b, - 0xd6, 0xf8, 0xf0, 0x62, 0xf0, 0x56, 0x07, 0x0f, 0x97, 0x83, 0x3f, 0xd1, - 0xff, 0x6b, 0x76, 0x09, 0x24, 0x4f, 0xd2, 0xed, 0xd5, 0x58, 0xc0, 0xac, - 0x9a, 0xa3, 0x37, 0x4a, 0xdc, 0xe8, 0xf2, 0x47, 0xcd, 0xe5, 0x7e, 0x17, - 0xa7, 0x23, 0x34, 0xfe, 0x8d, 0x81, 0x8d, 0x89, 0xb4, 0xef, 0xc6, 0x01, - 0xdd, 0xc5, 0x1e, 0x9d, 0xfb, 0x1a, 0x86, 0x0b, 0xbc, 0x3e, 0x87, 0xe3, - 0xd7, 0x1a, 0x16, 0x6c, 0xc0, 0x3c, 0x2a, 0x0f, 0xb9, 0x23, 0x4b, 0x75, - 0xa4, 0x59, 0xc7, 0x79, 0xea, 0xe1, 0x12, 0x55, 0x3c, 0xc0, 0x98, 0x4d, - 0x12, 0x81, 0xd8, 0x34, 0xb0, 0xb9, 0x18, 0x48, 0xad, 0x96, 0x02, 0x3b, - 0xcd, 0xb7, 0xbf, 0xa8, 0x72, 0xd4, 0x20, 0xbc, 0xdd, 0xa1, 0x58, 0xc0, - 0x32, 0xf7, 0xb8, 0x9d, 0xcc, 0x26, 0x63, 0x67, 0xb6, 0x9b, 0x0c, 0x6b, - 0xb3, 0x1f, 0x78, 0x14, 0xa6, 0xeb, 0x6f, 0x5d, 0x2e, 0x6c, 0x2c, 0x08, - 0x7e, 0xdd, 0xbd, 0xb5, 0x7d, 0x5f, 0x2e, 0x01, 0x11, 0xec, 0xdd, 0x71, - 0x8f, 0x78, 0xbb, 0x0b, 0x84, 0xff, 0x0a, 0x80, 0x23, 0x3d, 0x3f, 0x45, - 0x31, 0x1a, 0x23, 0xfd, 0x35, 0x9e, 0xad, 0xe2, 0x39, 0x0c, 0xb3, 0xad, - 0xb0, 0x5e, 0x17, 0xc8, 0xeb, 0xd0, 0x60, 0xa7, 0x80, 0x58, 0x2d, 0x13, - 0x2c, 0xb4, 0x05, 0x87, 0x48, 0xa1, 0xa6, 0xcb, 0x50, 0x6e, 0xcb, 0xf1, - 0x66, 0x64, 0xba, 0x11, 0x5c, 0x38, 0x7a, 0x18, 0x2c, 0x98, 0x15, 0x92, - 0xd4, 0x36, 0x68, 0xcd, 0x7c, 0xe8, 0xcd, 0x64, 0xc0, 0x57, 0xf0, 0xec, - 0xcd, 0x66, 0xe8, 0x68, 0xc7, 0x4c, 0xa7, 0xaf, 0xfe, 0x4d, 0xbf, 0xfa, - 0xef, 0xff, 0x4d, 0xbe, 0x6a, 0xa7, 0xff, 0x50, 0x2f, 0xb2, 0xdd, 0x27, - 0xb6, 0xb6, 0x5b, 0xbf, 0x76, 0xfb, 0xb1, 0xb8, 0x48, 0x16, 0x73, 0x57, - 0xe1, 0x65, 0x0d, 0x9b, 0x68, 0xfc, 0x35, 0x2d, 0x72, 0x60, 0xfd, 0xb6, - 0x1f, 0x11, 0x9b, 0x1d, 0x4d, 0x1f, 0xec, 0xc4, 0x62, 0x92, 0xe8, 0xf8, - 0x59, 0xad, 0x87, 0x05, 0x24, 0xdd, 0xf7, 0x0e, 0x85, 0xe7, 0xe9, 0x66, - 0x36, 0xcc, 0xd4, 0x34, 0x74, 0x32, 0xcc, 0xc6, 0x81, 0x65, 0x14, 0x0a, - 0x2d, 0xfd, 0xc9, 0x0c, 0xae, 0xd1, 0x47, 0xed, 0x87, 0x92, 0x9e, 0xd7, - 0xef, 0x8b, 0x86, 0x05, 0x9e, 0x4a, 0x7f, 0x31, 0x21, 0xc4, 0x0c, 0x98, - 0xcd, 0xa3, 0x9a, 0x94, 0x7e, 0x5b, 0xab, 0x9b, 0xb9, 0x58, 0x76, 0x67, - 0x3f, 0xc0, 0xf5, 0x90, 0x8c, 0x16, 0x50, 0x48, 0xa2, 0x42, 0x72, 0xab, - 0x31, 0x04, 0xf9, 0xaf, 0xe9, 0x56, 0x3d, 0x0e, 0xbb, 0x9d, 0x53, 0x64, - 0x1a, 0x63, 0xf3, 0x9f, 0xfb, 0xe5, 0xbf, 0x34, 0xed, 0x68, 0x44, 0x5c, - 0x60, 0xad, 0xfd, 0xcd, 0xfe, 0x39, 0x5c, 0x6d, 0xcc, 0x1f, 0xf4, 0x99, - 0xff, 0x1a, 0xeb, 0x7d, 0xd4, 0x3f, 0x1f, 0xb5, 0xde, 0x76, 0x17, 0x17, - 0xfb, 0xb3, 0x73, 0x4f, 0x9c, 0xbb, 0xdd, 0x56, 0xc9, 0xc3, 0xce, 0x72, - 0x53, 0x5c, 0xa5, 0x66, 0x60, 0xb7, 0x71, 0x77, 0xdf, 0x54, 0xca, 0x32, - 0x26, 0xfd, 0x32, 0x8e, 0xed, 0xf4, 0xa8, 0x1b, 0x9d, 0x6e, 0xfb, 0xc8, - 0x71, 0xba, 0x68, 0xd3, 0x01, 0x50, 0x08, 0x48, 0xd7, 0xa8, 0xe8, 0x05, - 0x64, 0x8a, 0x72, 0xa5, 0x8c, 0x7d, 0x6d, 0xea, 0x82, 0x1e, 0xb3, 0x7c, - 0x8d, 0xb0, 0x6a, 0xda, 0x2a, 0x31, 0xbf, 0x01, 0xda, 0xf6, 0x3e, 0xda, - 0xf9, 0x8c, 0x36, 0xdc, 0x47, 0x7b, 0x26, 0xc2, 0xdf, 0x0d, 0xed, 0xf2, - 0x05, 0x68, 0xc7, 0x33, 0xda, 0xf2, 0x70, 0xb4, 0xc3, 0xdf, 0x0c, 0xed, - 0xf4, 0x70, 0xb4, 0x57, 0xfc, 0xd7, 0x5c, 0x67, 0xbb, 0xe5, 0xbc, 0x99, - 0x71, 0x2d, 0x80, 0x0b, 0x40, 0xaf, 0xdb, 0x21, 0x44, 0xa5, 0xd7, 0xb5, - 0xa6, 0xd0, 0xa2, 0xc9, 0xa8, 0x07, 0x65, 0x7a, 0x08, 0x1f, 0xb2, 0x71, - 0x33, 0xc2, 0x36, 0x2b, 0x06, 0xd4, 0x74, 0x1d, 0xd4, 0xf4, 0x8a, 0x01, - 0x5a, 0x01, 0xa5, 0x49, 0xbe, 0x62, 0x26, 0x82, 0xa4, 0xb6, 0x55, 0x7d, - 0x0c, 0x66, 0xca, 0x78, 0x6a, 0xf0, 0x9d, 0xde, 0xdf, 0x8e, 0x5b, 0xf5, - 0xe4, 0x9e, 0xc1, 0x27, 0x7d, 0x63, 0x7e, 0x9f, 0xf8, 0x91, 0x8b, 0x06, - 0xaa, 0x98, 0x6d, 0x7c, 0x5e, 0x0a, 0x33, 0x99, 0x53, 0xcd, 0x64, 0x46, - 0xac, 0xc4, 0x26, 0x72, 0x88, 0x47, 0x7d, 0xef, 0xf0, 0xbd, 0xc3, 0xad, - 0x0e, 0x09, 0x1d, 0x82, 0x72, 0x94, 0x66, 0x8f, 0xc9, 0x72, 0x1f, 0xc8, - 0x72, 0xa9, 0xf2, 0xe4, 0x04, 0x9e, 0xb4, 0x7c, 0x36, 0x12, 0x33, 0x52, - 0x97, 0x41, 0xae, 0xd6, 0xbc, 0xf6, 0x0f, 0x45, 0x43, 0x1a, 0x9a, 0xdb, - 0xd6, 0xfb, 0x50, 0x2e, 0x20, 0x40, 0xc5, 0x05, 0x27, 0xd8, 0x75, 0xa2, - 0x64, 0xe1, 0x68, 0x5d, 0x5c, 0xf4, 0xf0, 0x45, 0x95, 0xcd, 0x01, 0x2b, - 0x70, 0xe1, 0x8d, 0x58, 0x49, 0x8f, 0xab, 0xf6, 0x5c, 0x9a, 0x43, 0xc5, - 0x44, 0xaa, 0x45, 0x05, 0x0c, 0x50, 0x8f, 0xa6, 0x31, 0x8a, 0x99, 0x0d, - 0x13, 0x82, 0x9d, 0xfa, 0x3d, 0x62, 0x6e, 0xab, 0x05, 0x89, 0x54, 0x97, - 0xa8, 0xe1, 0xaa, 0x01, 0x22, 0x99, 0x96, 0xae, 0x4a, 0x0f, 0x70, 0xd8, - 0xcd, 0x8f, 0xf9, 0xa8, 0xad, 0xfd, 0x74, 0xff, 0x7f, 0x93, 0x3b, 0xcc, - 0x56, 0x11, 0x81, 0x3c, 0xfe, 0x8a, 0x70, 0x62, 0x90, 0x75, 0x0f, 0xd8, - 0x95, 0xc9, 0xe2, 0x02, 0xad, 0xcf, 0xf1, 0x7b, 0xc7, 0x7f, 0x52, 0x47, - 0xf5, 0x5a, 0x8d, 0x25, 0x3d, 0x6b, 0x51, 0xec, 0x8c, 0x33, 0xee, 0x0d, - 0xc6, 0xf6, 0xc6, 0xe6, 0x2b, 0x25, 0x99, 0x87, 0xd7, 0x06, 0x39, 0x28, - 0x19, 0x02, 0x72, 0xa8, 0xd0, 0x32, 0xc9, 0x59, 0x21, 0x52, 0x4c, 0x5c, - 0x96, 0x85, 0x66, 0xac, 0x9f, 0x5e, 0xc7, 0x53, 0x4b, 0x71, 0x45, 0x0b, - 0x79, 0x4a, 0x18, 0x59, 0xe3, 0x24, 0x3f, 0x01, 0xaf, 0x1c, 0x63, 0x7a, - 0x4a, 0x3e, 0x2d, 0x9a, 0x6a, 0xc0, 0xf1, 0x95, 0x50, 0x5e, 0x35, 0xa0, - 0xbc, 0xaa, 0x65, 0x85, 0x56, 0x40, 0x85, 0x56, 0xa7, 0x51, 0xd4, 0x5c, - 0xcf, 0xb1, 0x41, 0x4a, 0x74, 0xac, 0xbe, 0xe6, 0x23, 0xf5, 0x55, 0x42, - 0x18, 0x97, 0x25, 0x3a, 0x56, 0x78, 0x13, 0x44, 0x3f, 0x59, 0x30, 0xf7, - 0x57, 0x44, 0x7c, 0x37, 0x96, 0xe8, 0xbc, 0x12, 0xdc, 0x86, 0x42, 0xf5, - 0xc1, 0x86, 0x24, 0x6e, 0x79, 0x09, 0xdc, 0x1f, 0x88, 0xbb, 0x31, 0x7b, - 0xc1, 0xdc, 0xeb, 0x96, 0x01, 0xfa, 0xbb, 0x5f, 0xa4, 0xd3, 0x17, 0xdd, - 0xf9, 0x8b, 0x50, 0x2d, 0x8e, 0x05, 0xbb, 0x77, 0xa8, 0x52, 0x6a, 0x6a, - 0x82, 0xa0, 0xe5, 0x17, 0xc9, 0x6d, 0xf8, 0xc2, 0x22, 0xb2, 0xf5, 0x8c, - 0x32, 0x63, 0xe4, 0x6d, 0x94, 0x43, 0x45, 0xb9, 0x5e, 0xa0, 0x0c, 0xe7, - 0x59, 0x82, 0x83, 0xfe, 0x7e, 0x93, 0xe1, 0xc8, 0xab, 0xc9, 0x70, 0xe4, - 0xd5, 0x64, 0x2e, 0x96, 0xd1, 0xde, 0x5b, 0xc6, 0x43, 0xb6, 0xe9, 0x72, - 0x19, 0x87, 0xc9, 0x98, 0xd0, 0xe0, 0xea, 0x01, 0xff, 0x5f, 0x70, 0x45, - 0x9c, 0x44, 0xab, 0xc0, 0xf4, 0xc3, 0xdc, 0xc0, 0x06, 0xe9, 0x12, 0x91, - 0xf8, 0x6a, 0x28, 0x6a, 0xa5, 0x96, 0x4c, 0x6c, 0x6c, 0xea, 0x61, 0xa7, - 0x32, 0x3c, 0xe2, 0xba, 0x70, 0xe2, 0x87, 0xfc, 0xac, 0x61, 0xe4, 0x79, - 0x3a, 0x41, 0x6d, 0xf0, 0xc0, 0xf5, 0x7a, 0x64, 0xd7, 0x12, 0x5e, 0xc7, - 0x89, 0xeb, 0x84, 0xc9, 0x2c, 0x18, 0x20, 0xca, 0x41, 0xeb, 0xd6, 0x5e, - 0xa0, 0xae, 0x53, 0x4e, 0x46, 0x5a, 0x05, 0xaa, 0x24, 0x7e, 0xac, 0x66, - 0xc3, 0x7c, 0xb2, 0x2b, 0xb6, 0xaa, 0x02, 0x5c, 0xb0, 0x39, 0x51, 0xbd, - 0xcf, 0xc1, 0x74, 0x69, 0x31, 0x61, 0x9b, 0x39, 0xab, 0xf6, 0x56, 0x26, - 0x58, 0x1f, 0xd3, 0x21, 0x56, 0xf9, 0x9e, 0x40, 0xcc, 0x0c, 0xfe, 0xa0, - 0x66, 0xd8, 0xc8, 0x40, 0x23, 0xf8, 0x64, 0x02, 0x9f, 0x50, 0x5b, 0x93, - 0x5f, 0x2e, 0x59, 0x31, 0xa0, 0x63, 0x40, 0xc7, 0x68, 0x18, 0x2d, 0x7d, - 0x67, 0xbb, 0x82, 0x60, 0x59, 0xd5, 0xf2, 0x23, 0x3a, 0x4c, 0xe8, 0x90, - 0xd1, 0x21, 0xa3, 0x43, 0xc6, 0x54, 0x69, 0xcb, 0x30, 0xc3, 0x69, 0x80, - 0x08, 0x4c, 0x03, 0x46, 0x74, 0xb8, 0x15, 0x72, 0x48, 0xd6, 0x61, 0x46, - 0x07, 0x78, 0x5d, 0xc5, 0x33, 0xdb, 0x14, 0xff, 0xdb, 0xa2, 0xe8, 0x62, - 0x71, 0x26, 0xd8, 0x41, 0x53, 0x5e, 0x12, 0xea, 0x40, 0xc9, 0xdb, 0x23, - 0xbb, 0x33, 0x05, 0x03, 0x3a, 0x3c, 0x7e, 0x37, 0xef, 0x76, 0xb8, 0xc1, - 0x51, 0xaf, 0x70, 0x1c, 0xbd, 0xc1, 0x11, 0x6a, 0x3c, 0x19, 0xc1, 0x93, - 0x01, 0xfe, 0x57, 0x5f, 0x99, 0x76, 0xa1, 0x83, 0x16, 0x2d, 0xb9, 0x51, - 0x06, 0x84, 0x43, 0x7f, 0x2a, 0xc8, 0x50, 0x24, 0x3b, 0x17, 0x17, 0x9d, - 0x06, 0xec, 0x3a, 0x9d, 0x08, 0xae, 0x13, 0xbe, 0xc8, 0xa7, 0xf3, 0x97, - 0xb5, 0x9d, 0x9b, 0xbb, 0x99, 0xf8, 0x62, 0x82, 0x4c, 0xb2, 0x3c, 0x8a, - 0xd6, 0xfa, 0x52, 0xa5, 0xbb, 0xc1, 0x8a, 0x9c, 0xb1, 0x1a, 0x5e, 0x5d, - 0x49, 0x0e, 0xb4, 0x75, 0x3d, 0xe7, 0xec, 0xc5, 0xb6, 0xf4, 0x93, 0xa5, - 0xb3, 0x6f, 0x9f, 0x6f, 0x97, 0xab, 0x6d, 0x6a, 0x46, 0x3f, 0x0a, 0x5c, - 0xf5, 0x3b, 0xaf, 0x7b, 0x66, 0x9d, 0x85, 0x15, 0x8c, 0x59, 0x03, 0x0d, - 0x3d, 0x71, 0xed, 0x9b, 0xc9, 0xae, 0x13, 0x06, 0x21, 0x02, 0x0e, 0x34, - 0x2e, 0x1b, 0xbe, 0xa6, 0x40, 0x34, 0x89, 0x68, 0x0a, 0xd0, 0x78, 0x1d, - 0x7b, 0x2f, 0xca, 0x63, 0xd4, 0x41, 0x6f, 0x29, 0x51, 0xcf, 0x0c, 0x4d, - 0x2a, 0x51, 0xd1, 0xb4, 0xb2, 0xb9, 0x8b, 0xde, 0x60, 0x61, 0x5c, 0xe0, - 0x9d, 0xa1, 0x09, 0xa2, 0x83, 0xa7, 0xc6, 0xc2, 0xd0, 0x8a, 0x46, 0xf7, - 0xd7, 0x06, 0x05, 0x54, 0x71, 0x2c, 0x11, 0x94, 0x9e, 0x13, 0x0c, 0xb2, - 0x4c, 0x7f, 0xe3, 0x07, 0x43, 0xa3, 0x09, 0xde, 0x49, 0x6e, 0x20, 0x01, - 0x80, 0x51, 0x07, 0x19, 0x9a, 0x20, 0x19, 0x5f, 0xab, 0xb3, 0x9f, 0x0c, - 0x4d, 0x12, 0x07, 0xc9, 0xf4, 0x78, 0x83, 0xa0, 0xc4, 0x6a, 0x3a, 0x7d, - 0xd0, 0xcc, 0xc2, 0xa4, 0x83, 0x0c, 0x4d, 0x42, 0xd6, 0xba, 0x51, 0x87, - 0xc9, 0x02, 0x17, 0x4d, 0x34, 0x56, 0x47, 0xd1, 0xe8, 0xa0, 0xec, 0xa4, - 0x3c, 0x9e, 0x59, 0x2a, 0x32, 0x75, 0xf0, 0x93, 0xc6, 0xde, 0x14, 0xec, - 0x66, 0x09, 0xb9, 0x1e, 0xf9, 0x8c, 0x26, 0x14, 0x4b, 0x55, 0xc8, 0x20, - 0x43, 0xc3, 0x94, 0x47, 0xcb, 0x5c, 0x4a, 0xcf, 0xac, 0xd7, 0x50, 0x90, - 0x26, 0x94, 0x41, 0x43, 0x41, 0x5d, 0x49, 0xa8, 0xd9, 0x5f, 0xab, 0x4a, - 0x40, 0x06, 0x6f, 0x6b, 0x90, 0x26, 0x5b, 0x99, 0xe0, 0x9b, 0x1b, 0x24, - 0xf8, 0xb2, 0xa2, 0x69, 0x71, 0x26, 0xd8, 0x20, 0xcb, 0xae, 0xa8, 0x0d, - 0xbb, 0xea, 0x20, 0x45, 0x13, 0xed, 0xb8, 0x9a, 0xe9, 0x2c, 0xfe, 0xd5, - 0x3e, 0x60, 0xd6, 0x89, 0x22, 0x34, 0x42, 0xde, 0x50, 0x1b, 0xe2, 0x85, - 0x7e, 0xb1, 0x78, 0xd1, 0x87, 0xc9, 0x54, 0x43, 0xdd, 0xe7, 0xe5, 0xd6, - 0xff, 0x18, 0x34, 0xc1, 0x48, 0x43, 0x87, 0x1f, 0x05, 0x13, 0xee, 0xf8, - 0x6f, 0x67, 0x6b, 0x42, 0xa2, 0x04, 0xf2, 0xa1, 0x55, 0x91, 0xbf, 0x05, - 0x82, 0x11, 0xf3, 0x9d, 0xb0, 0x80, 0x8c, 0x15, 0xb1, 0xf2, 0x87, 0x8a, - 0x93, 0xa5, 0x60, 0x1b, 0xa9, 0x42, 0x32, 0x8d, 0xb8, 0x4e, 0x40, 0x94, - 0x81, 0x68, 0x06, 0xa2, 0x05, 0x88, 0x56, 0x20, 0xda, 0x48, 0x4d, 0x22, - 0x1a, 0x8f, 0x88, 0xbe, 0x6c, 0x26, 0xd9, 0x66, 0x12, 0x21, 0xda, 0x38, - 0x96, 0xe4, 0x14, 0x92, 0x63, 0x49, 0x6c, 0x49, 0x39, 0x96, 0xde, 0x97, - 0x83, 0xc7, 0x77, 0xb6, 0xe9, 0xfc, 0xa9, 0x02, 0x10, 0x73, 0x3b, 0x13, - 0x33, 0x83, 0x98, 0x7c, 0x2e, 0x61, 0x05, 0x82, 0x8d, 0x1e, 0xe2, 0x93, - 0x62, 0x31, 0x9c, 0x9f, 0x60, 0xf3, 0x65, 0x3a, 0x86, 0xc9, 0x44, 0x7f, - 0x8d, 0x66, 0x62, 0xee, 0xca, 0xd3, 0xb2, 0x85, 0x43, 0xf5, 0x0b, 0xd5, - 0xd4, 0xfb, 0x05, 0x9e, 0xd9, 0x3b, 0x1c, 0xd0, 0x0b, 0x4e, 0xf2, 0x4b, - 0x5b, 0x60, 0x38, 0x99, 0x5d, 0xb4, 0x2a, 0x0e, 0xe6, 0x17, 0xcd, 0x0f, - 0x1e, 0x5b, 0xdb, 0x1f, 0x8e, 0xa0, 0x54, 0xdb, 0x62, 0x84, 0x6d, 0x31, - 0xe1, 0x64, 0xce, 0x35, 0x1a, 0xa5, 0x94, 0x33, 0xf7, 0x94, 0x0e, 0xed, - 0x73, 0xd8, 0x1c, 0xaf, 0xb0, 0xf6, 0x37, 0x58, 0xfb, 0xfb, 0x6a, 0x83, - 0x58, 0x01, 0x32, 0x6c, 0x91, 0x15, 0xb6, 0x88, 0x39, 0xd5, 0x46, 0x44, - 0x8d, 0x7f, 0x3d, 0x35, 0xcd, 0x6c, 0x0f, 0x10, 0xf4, 0xba, 0x0b, 0xaa, - 0x9c, 0xc5, 0x04, 0x51, 0x57, 0x66, 0x1f, 0x90, 0x87, 0xba, 0x7d, 0x94, - 0x81, 0x85, 0xfb, 0xee, 0x96, 0x47, 0xc2, 0xfe, 0x07, 0x5c, 0x2f, 0x63, - 0x07, 0xdb, 0x29, 0xb8, 0xb0, 0xc1, 0x18, 0xdf, 0x6a, 0x08, 0x5d, 0x31, - 0x1c, 0x0d, 0x90, 0xb6, 0x80, 0xa4, 0xc1, 0xb9, 0x1a, 0x8a, 0xa2, 0x39, - 0x90, 0x10, 0x24, 0xbd, 0xf0, 0x58, 0x3a, 0x50, 0xec, 0x92, 0xc4, 0xf9, - 0x7e, 0x74, 0x9e, 0x93, 0xc5, 0xea, 0xce, 0x31, 0xc4, 0xed, 0x1c, 0x64, - 0x3c, 0x46, 0x21, 0x95, 0x04, 0x2d, 0xb9, 0x37, 0x99, 0xc7, 0xb2, 0x04, - 0x13, 0xa2, 0x6d, 0x40, 0x1c, 0xe5, 0x49, 0xb1, 0x73, 0x6b, 0xc6, 0xfd, - 0x57, 0xc6, 0x74, 0x02, 0xac, 0x43, 0x86, 0x39, 0xde, 0x31, 0x9a, 0x93, - 0x8e, 0xe1, 0x8e, 0x5e, 0x23, 0x10, 0xdc, 0x63, 0x3d, 0x9c, 0x57, 0x1a, - 0xa0, 0x11, 0xcc, 0xf0, 0xf2, 0x9e, 0x3d, 0x4c, 0x4e, 0x24, 0x07, 0xde, - 0xf5, 0x4d, 0xbe, 0x4e, 0x87, 0xde, 0xe4, 0x32, 0xe3, 0x44, 0x17, 0x52, - 0x68, 0x99, 0xcd, 0x00, 0x1a, 0x89, 0x4f, 0x9a, 0xcd, 0x60, 0x56, 0xe2, - 0x7d, 0x54, 0xca, 0x46, 0x7b, 0xa0, 0x94, 0x94, 0x75, 0x9b, 0x77, 0xc4, - 0x75, 0x8e, 0xf8, 0x82, 0xf9, 0xeb, 0x27, 0xfc, 0x02, 0xd7, 0x15, 0x1d, - 0x14, 0xff, 0x2f, 0xf8, 0x5f, 0xac, 0x1d, 0xf1, 0x92, 0x35, 0xa6, 0x1c, - 0x8b, 0xda, 0x19, 0x42, 0x28, 0x65, 0xfa, 0xf7, 0xc5, 0x0c, 0x15, 0xa3, - 0x64, 0x44, 0x58, 0xa8, 0xaf, 0x0f, 0x6a, 0x7d, 0xac, 0x11, 0xa6, 0xa5, - 0xc6, 0x8d, 0xfa, 0x1a, 0x50, 0xfa, 0x58, 0x05, 0x75, 0x39, 0x71, 0xb4, - 0x4b, 0xf4, 0xb7, 0xea, 0xe0, 0x61, 0xb0, 0xe7, 0xe0, 0x87, 0xb7, 0x60, - 0x18, 0x86, 0xc3, 0x36, 0x72, 0xd4, 0x33, 0x70, 0xd4, 0x1b, 0x18, 0x75, - 0xce, 0x72, 0xe4, 0x49, 0x6a, 0x87, 0x17, 0x60, 0xda, 0x8c, 0xa3, 0xc1, - 0xb9, 0xba, 0x37, 0x4b, 0xac, 0xa8, 0x37, 0x37, 0xd8, 0x91, 0x29, 0xa4, - 0x96, 0xdd, 0x13, 0x0d, 0xbf, 0xf8, 0x71, 0x90, 0xac, 0xe1, 0xe7, 0x06, - 0xb6, 0x35, 0xe3, 0x8b, 0x05, 0x5f, 0xac, 0x90, 0x51, 0x0f, 0x3e, 0xd2, - 0xf7, 0x3a, 0xe8, 0xc5, 0x80, 0xa5, 0x2a, 0x8a, 0xb9, 0xa9, 0x6e, 0x28, - 0xc5, 0xdf, 0xbd, 0xcf, 0x6a, 0x7e, 0xb8, 0x67, 0xfc, 0x0d, 0x3f, 0x78, - 0x30, 0x7a, 0x3b, 0xc8, 0xc5, 0xf9, 0x62, 0xc9, 0xe0, 0xdb, 0x97, 0xe5, - 0x70, 0x29, 0xb7, 0x2f, 0x96, 0xf5, 0xbc, 0x7d, 0xc9, 0xf5, 0xd2, 0xdd, - 0xb9, 0x4c, 0x8d, 0x9f, 0x42, 0x57, 0x97, 0xb1, 0x4a, 0xf9, 0xd5, 0xa5, - 0xa9, 0x97, 0x70, 0xfb, 0xf2, 0xd8, 0x35, 0x1f, 0x97, 0xfe, 0x88, 0x35, - 0x1f, 0x96, 0xfe, 0x98, 0x35, 0x4f, 0x9f, 0x58, 0xf3, 0x61, 0xe9, 0x8f, - 0x58, 0xf3, 0xf6, 0xfb, 0xd6, 0xbc, 0xfc, 0xbe, 0x35, 0xe7, 0xdf, 0xb7, - 0xe6, 0xf1, 0xfe, 0x9a, 0xcb, 0xe7, 0xd7, 0xec, 0x25, 0xef, 0x72, 0x27, - 0x3f, 0xa9, 0x3b, 0x88, 0xac, 0xca, 0x70, 0x53, 0x65, 0xb9, 0x85, 0xc4, - 0x5c, 0x06, 0x5a, 0x16, 0x9e, 0xd4, 0xe7, 0x94, 0xc4, 0x55, 0x1e, 0x3d, - 0x9f, 0xec, 0x90, 0x42, 0x83, 0x35, 0x53, 0x23, 0xf1, 0xa4, 0x6e, 0x60, - 0xa4, 0x4c, 0xc9, 0x5c, 0x46, 0xb1, 0x6c, 0xa8, 0xd3, 0x34, 0x4c, 0xf2, - 0xc3, 0x59, 0xe9, 0x45, 0xd3, 0x4a, 0x1b, 0x73, 0x2f, 0x2f, 0x70, 0x52, - 0xcf, 0x55, 0x6d, 0xae, 0xd5, 0x32, 0xb5, 0x0e, 0x13, 0x3a, 0xcc, 0x5f, - 0xdc, 0xe1, 0xde, 0x2d, 0xcc, 0x7e, 0x63, 0x07, 0x0d, 0x13, 0x74, 0x6a, - 0x6f, 0xb8, 0x66, 0xd6, 0x49, 0xf6, 0xf4, 0x86, 0x61, 0xd0, 0x4d, 0xd1, - 0x12, 0xab, 0x73, 0x6f, 0x87, 0xe0, 0xd2, 0x9a, 0x1b, 0xbc, 0xe9, 0x4e, - 0x05, 0xd3, 0xcc, 0xe2, 0xe9, 0x4c, 0x42, 0xfa, 0x58, 0x35, 0xf3, 0xfc, - 0x7b, 0x34, 0x73, 0xb2, 0xcd, 0x33, 0x54, 0x63, 0x35, 0x65, 0x89, 0x21, - 0xdc, 0xd9, 0xcd, 0xf6, 0xce, 0x6e, 0x8a, 0xdd, 0x25, 0x93, 0x94, 0xdd, - 0x94, 0xa0, 0x84, 0x04, 0x45, 0x66, 0x1c, 0x40, 0x0b, 0xec, 0x55, 0x6e, - 0x96, 0x31, 0xcb, 0x99, 0x92, 0x3c, 0xe3, 0x3c, 0xa1, 0xf3, 0xac, 0x86, - 0xed, 0xa6, 0x8b, 0x53, 0xf2, 0xe2, 0x9c, 0x75, 0xe3, 0x3c, 0x61, 0x89, - 0x01, 0x7c, 0xd9, 0xff, 0x71, 0x1d, 0x22, 0x3a, 0x5c, 0xc6, 0x16, 0xa7, - 0x6a, 0xd7, 0xc7, 0x8b, 0x55, 0xe8, 0x32, 0x7f, 0xb9, 0x60, 0x98, 0x82, - 0xf7, 0x1b, 0x44, 0x54, 0x87, 0x04, 0x18, 0xf6, 0x30, 0x50, 0x25, 0x88, - 0x23, 0x0c, 0x23, 0xc6, 0x7c, 0xcd, 0xa3, 0xe3, 0x3a, 0x05, 0xec, 0x01, - 0x3d, 0x3c, 0xdf, 0x0b, 0xfb, 0xc2, 0xb3, 0x81, 0x3c, 0x57, 0x47, 0xdf, - 0x4d, 0xcf, 0x23, 0x46, 0x1b, 0x68, 0x4b, 0x5c, 0x9a, 0x1b, 0xb1, 0xc5, - 0x54, 0x63, 0xcf, 0x66, 0xab, 0x76, 0x88, 0x0a, 0x48, 0xb0, 0x09, 0x8a, - 0xc3, 0x4c, 0xcd, 0x84, 0x11, 0xd1, 0x50, 0xdb, 0xcd, 0x9a, 0x8a, 0xfb, - 0xd2, 0x7d, 0x5a, 0xc8, 0x63, 0x23, 0x78, 0x8a, 0xcf, 0x7f, 0x5a, 0xa4, - 0xb5, 0x58, 0x28, 0xc9, 0xe6, 0x7f, 0x65, 0xe4, 0x1f, 0x56, 0x2e, 0x82, - 0xe6, 0x25, 0xdc, 0x62, 0xdd, 0x88, 0xa2, 0x59, 0x68, 0xf6, 0xa8, 0xab, - 0xdc, 0x99, 0x4d, 0xda, 0xb8, 0x3d, 0x24, 0x12, 0x76, 0x41, 0xfe, 0x00, - 0xff, 0xaa, 0xa5, 0xd9, 0x1f, 0xe1, 0xc5, 0x72, 0xc3, 0xdc, 0xf6, 0x0c, - 0xd8, 0xc9, 0xb6, 0x9a, 0xf7, 0x16, 0x3e, 0x3e, 0xd8, 0xfd, 0xbf, 0x55, - 0x23, 0xb4, 0x30, 0x79, 0x99, 0x2f, 0xf2, 0x9f, 0x05, 0x28, 0x4a, 0x95, - 0xb5, 0x8d, 0xd2, 0x7a, 0x50, 0xa9, 0x01, 0xdb, 0xe7, 0xdb, 0x95, 0xb0, - 0x3d, 0xc3, 0xcd, 0x14, 0xaa, 0x5b, 0xbc, 0x0f, 0x9c, 0xc5, 0x2b, 0x28, - 0x37, 0xc6, 0xc1, 0xcd, 0x3f, 0xe9, 0x6b, 0xfc, 0x7b, 0x2d, 0x48, 0x1a, - 0x3d, 0x03, 0x6f, 0xbe, 0x83, 0xeb, 0x25, 0xde, 0xa9, 0x48, 0xb7, 0x26, - 0xa7, 0x7e, 0x28, 0x1a, 0x03, 0xb0, 0x0f, 0x6d, 0xfe, 0x8c, 0xeb, 0x8a, - 0xad, 0xd2, 0x5e, 0xba, 0xde, 0x88, 0x4d, 0x24, 0x3b, 0x7b, 0x6e, 0xc9, - 0xf9, 0x5b, 0x70, 0xfd, 0x0a, 0xbe, 0x5e, 0x19, 0x2b, 0x0f, 0x38, 0x42, - 0x5e, 0x80, 0x31, 0x32, 0xa2, 0x0e, 0xf6, 0xdc, 0x5c, 0xa7, 0xd5, 0x14, - 0xf4, 0x70, 0x3c, 0xc0, 0x9d, 0xc1, 0xa0, 0x1e, 0x61, 0x18, 0x2f, 0x58, - 0x99, 0x67, 0xdf, 0x55, 0x66, 0xe3, 0x77, 0xa1, 0x60, 0x40, 0x68, 0x8b, - 0xd8, 0x91, 0x9f, 0x41, 0xe7, 0x85, 0x74, 0xbe, 0x62, 0xad, 0x74, 0x3c, - 0x55, 0x3a, 0x7b, 0x5a, 0xa8, 0x86, 0x54, 0x82, 0xba, 0x50, 0x2a, 0xb5, - 0x73, 0x82, 0x53, 0x3a, 0x40, 0x9c, 0x7f, 0x10, 0x9c, 0xce, 0xe0, 0xa6, - 0x25, 0x54, 0xdf, 0x4a, 0x58, 0x67, 0x84, 0xa1, 0x5f, 0x28, 0x23, 0xca, - 0x78, 0xd8, 0x91, 0xec, 0x81, 0x01, 0x6c, 0x00, 0xc5, 0xac, 0x5a, 0xfc, - 0xc6, 0x90, 0x9e, 0x37, 0xa4, 0xa4, 0x92, 0x11, 0x0f, 0xaa, 0xd1, 0xcf, - 0x8f, 0x0e, 0x1d, 0x94, 0x77, 0x19, 0xb6, 0x67, 0xa2, 0x69, 0x81, 0xa5, - 0x31, 0x36, 0x8f, 0x33, 0xf5, 0xe7, 0xe6, 0xeb, 0x7e, 0x86, 0xcf, 0xdf, - 0xf2, 0xd6, 0xe7, 0x41, 0x6f, 0x45, 0x3b, 0x03, 0xbf, 0xf2, 0xd4, 0xef, - 0x7f, 0xd2, 0xe3, 0x16, 0x55, 0xdf, 0x20, 0xb7, 0x34, 0xc9, 0xfe, 0xd1, - 0xed, 0xbc, 0xb2, 0x48, 0x51, 0xf4, 0xae, 0x35, 0x5f, 0x0b, 0x13, 0xcd, - 0xf2, 0xc6, 0xba, 0x59, 0x5e, 0x4a, 0x37, 0xcb, 0xdb, 0xe4, 0x46, 0xbb, - 0xe1, 0xbf, 0xe9, 0xdf, 0xff, 0xaa, 0x7f, 0xff, 0x53, 0xfe, 0x74, 0x96, - 0xf5, 0xc9, 0x3a, 0x9b, 0x49, 0x00, 0xb0, 0x50, 0x05, 0x80, 0xc4, 0x8a, - 0x88, 0x53, 0xc4, 0xa9, 0x30, 0x33, 0xe9, 0x98, 0x50, 0x2e, 0x83, 0x93, - 0x4a, 0x99, 0xc4, 0x42, 0x3d, 0xc6, 0xa4, 0x96, 0x3d, 0xb3, 0x92, 0x15, - 0x55, 0x1b, 0x16, 0x19, 0xb6, 0x48, 0x84, 0x99, 0x32, 0x96, 0x1c, 0xea, - 0x7c, 0xa0, 0x59, 0x2e, 0xca, 0x8e, 0x0b, 0x53, 0xff, 0x66, 0xd1, 0xeb, - 0x1d, 0x5b, 0xd8, 0xb6, 0x36, 0x29, 0x99, 0xe6, 0x40, 0x3b, 0x29, 0xd3, - 0x4b, 0x4d, 0x30, 0x2f, 0x0b, 0x1e, 0x64, 0x34, 0x1e, 0x37, 0x7b, 0x36, - 0xdb, 0x04, 0x74, 0x5e, 0x0b, 0xe2, 0x62, 0x51, 0x3b, 0x85, 0xc2, 0xd8, - 0xda, 0x0a, 0xb7, 0xd7, 0x2c, 0x6a, 0xe4, 0xd4, 0x0a, 0x15, 0xfd, 0xc8, - 0x8a, 0x05, 0xb3, 0xc7, 0x03, 0x4e, 0x5f, 0x0b, 0x92, 0x99, 0x01, 0x2e, - 0x84, 0xb4, 0xf7, 0xcf, 0x35, 0x38, 0x69, 0x95, 0xd6, 0xff, 0xa1, 0x7f, - 0xff, 0x87, 0xfe, 0xfd, 0xf7, 0xc7, 0x6d, 0xfa, 0xdd, 0xcf, 0xf2, 0x75, - 0x78, 0xf1, 0xe6, 0xe7, 0x91, 0x52, 0xf7, 0x99, 0xcf, 0xa4, 0x94, 0xc1, - 0x13, 0x1f, 0x4a, 0xab, 0x3e, 0xeb, 0xdd, 0x8c, 0x19, 0x2d, 0xea, 0x60, - 0x1e, 0xbb, 0xe5, 0x4c, 0xb7, 0xa6, 0x6e, 0x3f, 0x8a, 0x27, 0x26, 0x32, - 0x62, 0xe0, 0xa1, 0xba, 0xdc, 0xdd, 0x7e, 0x63, 0x42, 0xfb, 0x7b, 0xc1, - 0x0a, 0x49, 0xc9, 0xb7, 0x8f, 0x85, 0x21, 0xa6, 0xc6, 0xdc, 0xed, 0xed, - 0x8f, 0x7a, 0xe3, 0xa0, 0x93, 0x18, 0x0e, 0x82, 0x31, 0xc0, 0x14, 0x9b, - 0x79, 0x02, 0x45, 0x9c, 0x20, 0x77, 0x05, 0xc3, 0x66, 0x10, 0x74, 0x7e, - 0xba, 0x7f, 0x36, 0xb1, 0x54, 0x18, 0xe8, 0xb7, 0xf2, 0x65, 0x65, 0xda, - 0xf5, 0x2c, 0x18, 0x2b, 0x2b, 0x0d, 0x12, 0x12, 0x8e, 0x0b, 0x13, 0x1d, - 0x14, 0x0c, 0x2b, 0x21, 0x10, 0xda, 0x06, 0x33, 0xf1, 0x94, 0xb4, 0xc6, - 0x86, 0x4a, 0xd3, 0x56, 0x29, 0xfe, 0x6f, 0xdc, 0x62, 0x66, 0x39, 0x42, - 0x3d, 0x03, 0xb6, 0x06, 0x87, 0xc3, 0x08, 0x0e, 0xc8, 0xb0, 0x6f, 0x0e, - 0x39, 0x7a, 0xdd, 0x48, 0xbe, 0xf6, 0xa3, 0xb8, 0x3d, 0x88, 0x73, 0x69, - 0x82, 0x9d, 0x3b, 0x81, 0x81, 0x32, 0xae, 0x8c, 0x78, 0x7b, 0xe4, 0x3b, - 0x5e, 0x5f, 0x85, 0x34, 0x52, 0x6a, 0x23, 0xdb, 0xa6, 0xe5, 0xd6, 0x6d, - 0x41, 0xa8, 0xbd, 0xc0, 0x44, 0x2f, 0xc8, 0x14, 0x33, 0x86, 0xc8, 0x6b, - 0xbc, 0xba, 0x1e, 0xe6, 0x4c, 0x1b, 0xed, 0xf6, 0x35, 0x5d, 0x5d, 0xd7, - 0x7a, 0x55, 0xbb, 0x71, 0x32, 0x3b, 0xc1, 0x94, 0xe1, 0x16, 0x47, 0xbb, - 0xfe, 0xef, 0xa6, 0xa9, 0x71, 0x5a, 0x5e, 0x93, 0x5f, 0xd7, 0x8b, 0x6b, - 0xf1, 0xeb, 0x02, 0xca, 0x9f, 0xaf, 0x3c, 0x7d, 0xf5, 0xda, 0xd7, 0x6b, - 0x86, 0x30, 0xf2, 0x3a, 0x61, 0xc7, 0x26, 0xbb, 0xad, 0x97, 0x89, 0x8c, - 0x76, 0xbb, 0x82, 0xdb, 0x6c, 0x40, 0xcb, 0x2b, 0x93, 0xfe, 0xcb, 0x11, - 0xfd, 0x50, 0x53, 0xff, 0x19, 0x68, 0x26, 0xa0, 0x19, 0xc1, 0x10, 0x47, - 0x34, 0x5d, 0xb9, 0x2c, 0x60, 0xb8, 0x37, 0xbc, 0x5c, 0x0e, 0xe7, 0x6c, - 0x0e, 0x44, 0x98, 0xff, 0xd4, 0xeb, 0x1f, 0xfd, 0xf9, 0xb3, 0xd7, 0xf7, - 0x65, 0x74, 0x88, 0x30, 0x9e, 0xf1, 0x69, 0x0b, 0xb7, 0xc9, 0x3e, 0x5d, - 0xb9, 0x04, 0x98, 0x98, 0x2f, 0x17, 0xfd, 0xcb, 0x11, 0x63, 0x82, 0xfc, - 0x57, 0xfc, 0x50, 0x14, 0xf8, 0xf0, 0x60, 0x59, 0x2f, 0x10, 0x1e, 0x50, - 0xf0, 0xdf, 0xac, 0x8e, 0x09, 0xfc, 0x37, 0x42, 0x60, 0x7d, 0x39, 0x8d, - 0x28, 0xa7, 0x11, 0xd1, 0xff, 0xbd, 0xd6, 0x01, 0x8b, 0xdb, 0xbc, 0x36, - 0x60, 0xb4, 0x99, 0xfa, 0x80, 0xb1, 0xa9, 0x5e, 0x74, 0x5f, 0x2a, 0x27, - 0xf3, 0x9a, 0xb1, 0x58, 0xd6, 0x67, 0x2d, 0x44, 0x8d, 0xf0, 0xdb, 0xe6, - 0x93, 0x05, 0x11, 0x46, 0x4e, 0x6e, 0x69, 0xaa, 0xa8, 0xf0, 0x00, 0x6b, - 0xeb, 0xfa, 0xcd, 0x96, 0x08, 0x3e, 0xa0, 0x61, 0xe8, 0x87, 0xf4, 0xe8, - 0x15, 0xa5, 0x47, 0x00, 0x91, 0x84, 0x1e, 0xea, 0x80, 0x16, 0xfe, 0xba, - 0xef, 0x01, 0xde, 0x74, 0xe9, 0x03, 0x1a, 0x58, 0x6c, 0x13, 0xff, 0xdd, - 0x9b, 0x6e, 0xab, 0xdb, 0x1a, 0xcd, 0xdf, 0x16, 0x8c, 0x88, 0x76, 0x6e, - 0xcc, 0x9a, 0x6b, 0x50, 0x68, 0xc7, 0x96, 0x71, 0xf8, 0x45, 0xf1, 0x16, - 0xf5, 0x39, 0x4f, 0x3b, 0x7d, 0x7a, 0x71, 0x84, 0xec, 0x8d, 0xa1, 0xba, - 0x14, 0x8b, 0x7b, 0x49, 0xc8, 0x09, 0x47, 0x76, 0x14, 0x27, 0x5c, 0xce, - 0x41, 0xbc, 0x75, 0x44, 0x18, 0xe0, 0xb9, 0xfa, 0x2f, 0x63, 0x5f, 0xb3, - 0x89, 0xd6, 0x21, 0x79, 0xb8, 0x43, 0x23, 0x03, 0x13, 0xdf, 0x95, 0x52, - 0x2c, 0x50, 0x82, 0xd7, 0x8f, 0x90, 0xc3, 0x22, 0x5e, 0x4c, 0x12, 0xb0, - 0xd9, 0xad, 0xe6, 0xcd, 0xe9, 0xb3, 0x6b, 0xf8, 0x71, 0x0a, 0x35, 0x86, - 0x21, 0x1d, 0xb6, 0xb6, 0x46, 0xdc, 0xb4, 0x43, 0x8e, 0xb0, 0x1e, 0xcd, - 0x69, 0x53, 0x8f, 0xd7, 0x6a, 0xf9, 0x50, 0x08, 0x93, 0xa3, 0x85, 0x1c, - 0xec, 0x65, 0x4d, 0x8d, 0x04, 0x27, 0xcc, 0xdb, 0x9b, 0x5a, 0x4b, 0xeb, - 0xe4, 0x04, 0xaf, 0xaf, 0x76, 0x40, 0xe9, 0x78, 0xed, 0x30, 0x99, 0x2a, - 0xb7, 0x0e, 0x05, 0xaf, 0xd6, 0x58, 0xd9, 0x61, 0x46, 0x7e, 0x68, 0x34, - 0x02, 0xa5, 0x32, 0x58, 0x3f, 0xbc, 0xb6, 0xa8, 0xb7, 0x0e, 0xc1, 0x42, - 0x50, 0x3a, 0xdb, 0x60, 0x46, 0x4a, 0x66, 0x87, 0x77, 0x66, 0x24, 0xac, - 0x17, 0x1d, 0x3a, 0x6c, 0xbb, 0x77, 0x88, 0x46, 0x8b, 0x63, 0x87, 0x91, - 0x1d, 0xde, 0xdb, 0x8e, 0x2f, 0xa8, 0x75, 0x48, 0x1b, 0x58, 0x02, 0xb5, - 0x0d, 0xfd, 0xee, 0x06, 0x93, 0x25, 0x0e, 0x1d, 0x06, 0xef, 0x30, 0x58, - 0x07, 0x58, 0x28, 0xb9, 0xd1, 0x77, 0x3f, 0x83, 0x67, 0xee, 0x77, 0x98, - 0x6c, 0xd2, 0x78, 0x65, 0xc8, 0x1b, 0x23, 0xc9, 0x84, 0x30, 0xb7, 0x9d, - 0xbd, 0x9f, 0xea, 0xb0, 0x5e, 0x76, 0x08, 0xbb, 0x13, 0x7f, 0xec, 0xd0, - 0x5e, 0x74, 0x58, 0x0e, 0x1d, 0x46, 0xfe, 0x41, 0x07, 0xfd, 0x6e, 0xb1, - 0x2a, 0x33, 0xbc, 0x25, 0xa1, 0x35, 0xe2, 0x2c, 0x49, 0x19, 0xed, 0x5e, - 0x87, 0xfe, 0xdc, 0x41, 0x1e, 0x4a, 0xc5, 0x2b, 0x13, 0xc0, 0x6a, 0xb3, - 0xcf, 0x21, 0x68, 0xbc, 0x40, 0xf9, 0xa3, 0xf5, 0xbd, 0x01, 0x7f, 0xf8, - 0xe6, 0xb5, 0xe7, 0x0e, 0x41, 0x2c, 0xc4, 0xc9, 0xe4, 0x39, 0xe9, 0xae, - 0xad, 0xe8, 0x80, 0x0d, 0x8a, 0x12, 0x46, 0x40, 0x07, 0x61, 0x1a, 0x7d, - 0x20, 0x7b, 0xb5, 0x36, 0x80, 0x1a, 0x06, 0x1c, 0xcc, 0x4a, 0x93, 0x4d, - 0x99, 0xd1, 0x61, 0x51, 0xbd, 0xd2, 0x6a, 0x62, 0x31, 0x33, 0x74, 0xad, - 0x92, 0x07, 0x0d, 0x20, 0x11, 0xb7, 0xad, 0xe1, 0xeb, 0x7c, 0x7b, 0xea, - 0xdd, 0x82, 0xb7, 0xf8, 0x42, 0xd5, 0xea, 0xc4, 0xa3, 0x87, 0x2c, 0xd5, - 0xb0, 0xe5, 0xe4, 0x35, 0xc6, 0xf5, 0xc2, 0xb0, 0x9a, 0x65, 0x2d, 0x21, - 0x2d, 0x04, 0xc2, 0x11, 0xc2, 0x84, 0xf2, 0x0e, 0x10, 0x45, 0x2b, 0xb3, - 0x9e, 0x49, 0xe1, 0x62, 0xef, 0x69, 0xd9, 0x7c, 0x0b, 0x50, 0xed, 0xa2, - 0x4a, 0xcf, 0xa4, 0x3d, 0xc7, 0x02, 0x0f, 0xd5, 0x0a, 0x3a, 0x56, 0x1e, - 0x63, 0x6e, 0xc1, 0x0f, 0x05, 0x46, 0x2d, 0xbd, 0xca, 0x64, 0x3a, 0x3d, - 0x99, 0xb6, 0x5d, 0x68, 0x8b, 0x59, 0x4d, 0x91, 0xbc, 0xff, 0x12, 0xcf, - 0xd3, 0xc6, 0x93, 0xd5, 0xd0, 0x9d, 0xa3, 0x04, 0xf1, 0xe4, 0x87, 0xb5, - 0x07, 0x45, 0xab, 0x9f, 0x70, 0x71, 0xa0, 0xe2, 0xf6, 0xc7, 0xcf, 0x70, - 0x46, 0x99, 0x4e, 0x28, 0xfb, 0x33, 0xca, 0x78, 0x50, 0xee, 0xb8, 0xe7, - 0xe5, 0x2c, 0x0f, 0xe7, 0x09, 0xef, 0x79, 0x39, 0x89, 0xfe, 0x3c, 0x89, - 0x74, 0x1a, 0x51, 0xcf, 0xb4, 0x8a, 0xf2, 0xf2, 0x1e, 0x7e, 0x9e, 0x36, - 0xff, 0x97, 0x28, 0x81, 0xe2, 0xff, 0x70, 0x96, 0x58, 0x58, 0x9a, 0x38, - 0x4b, 0x03, 0x70, 0x2e, 0x83, 0x69, 0xe1, 0x7a, 0x34, 0x25, 0x9e, 0xdc, - 0x9b, 0x4f, 0x02, 0x9f, 0x7c, 0x18, 0x71, 0xe8, 0x50, 0x47, 0xa0, 0x43, - 0x7b, 0xee, 0xe0, 0x23, 0x38, 0xf9, 0x48, 0xc0, 0x61, 0x1d, 0x17, 0x1d, - 0xba, 0x73, 0x87, 0xfe, 0xd4, 0x81, 0x38, 0x2b, 0x39, 0xc2, 0x71, 0x0a, - 0x0e, 0x98, 0x0e, 0xc4, 0xea, 0xcb, 0x71, 0x93, 0x13, 0xbf, 0xec, 0x7d, - 0xa2, 0x89, 0xe3, 0x6f, 0x80, 0x06, 0x07, 0xf9, 0x5d, 0x07, 0xc7, 0x77, - 0x0d, 0x6a, 0x1d, 0x14, 0xb8, 0x25, 0x02, 0x5a, 0xee, 0x81, 0x22, 0x41, - 0x5d, 0xa9, 0x35, 0x2e, 0x87, 0x4c, 0xe3, 0x09, 0xd4, 0x3b, 0x28, 0x71, - 0xd1, 0xbd, 0x13, 0xfc, 0x06, 0xc8, 0x49, 0x33, 0x38, 0x51, 0x9d, 0x7a, - 0x37, 0x40, 0x81, 0x20, 0xdd, 0xca, 0xc5, 0x41, 0xa3, 0x81, 0x9e, 0x11, - 0xf4, 0xc1, 0x40, 0x9d, 0x83, 0xf4, 0xd7, 0x20, 0x26, 0x82, 0xd6, 0x33, - 0x68, 0x60, 0xaa, 0x64, 0xf6, 0xac, 0xed, 0xc0, 0xec, 0xea, 0x6c, 0x33, - 0xbc, 0x01, 0x1a, 0xe4, 0x75, 0x51, 0x28, 0x7b, 0xc8, 0x09, 0x3e, 0xf6, - 0xd6, 0x83, 0x8f, 0xaf, 0x40, 0xad, 0x83, 0x82, 0x9a, 0x12, 0xa3, 0xe9, - 0x03, 0xd3, 0x11, 0x41, 0x03, 0xbf, 0x17, 0xa0, 0x48, 0x50, 0x57, 0x58, - 0x7f, 0x1c, 0x55, 0x7b, 0x4d, 0x16, 0xf1, 0x08, 0x8c, 0xc1, 0xb9, 0xb1, - 0x05, 0x50, 0x52, 0x50, 0x26, 0xc8, 0xa2, 0xbb, 0x78, 0x99, 0x56, 0xaf, - 0x69, 0xc8, 0xad, 0xb1, 0x23, 0x40, 0x41, 0x83, 0x65, 0x26, 0x1d, 0x34, - 0xdf, 0x04, 0x05, 0x8b, 0x57, 0x20, 0x13, 0x9e, 0x68, 0x46, 0xf6, 0x50, - 0xb3, 0x67, 0x50, 0xe7, 0xa0, 0xc8, 0x33, 0xaf, 0x2b, 0x28, 0x39, 0xbe, - 0x05, 0x4a, 0x04, 0xf5, 0x06, 0xda, 0xdc, 0x0a, 0xf2, 0xa3, 0xc5, 0xc3, - 0xd8, 0x85, 0xd9, 0xcc, 0xb2, 0xb9, 0x84, 0xce, 0x2e, 0xcc, 0xb7, 0x40, - 0xad, 0x83, 0x02, 0x5a, 0xcc, 0x7f, 0x96, 0xe5, 0x16, 0x28, 0x12, 0x44, - 0x79, 0xf7, 0x18, 0xbb, 0xc6, 0x8a, 0xb2, 0x4d, 0x8e, 0xe9, 0x81, 0x89, - 0x31, 0x9e, 0xd5, 0x9c, 0x7a, 0xe9, 0xd1, 0xe3, 0x74, 0xd9, 0x6e, 0x81, - 0x0a, 0x8c, 0xe1, 0xec, 0xb1, 0x4a, 0x8f, 0xd9, 0xcc, 0x83, 0x87, 0x94, - 0x1c, 0x14, 0x08, 0x6a, 0x99, 0xe2, 0x5b, 0x02, 0x42, 0x4e, 0x96, 0x42, - 0xbf, 0x04, 0x3d, 0x71, 0x50, 0x24, 0xe8, 0x85, 0x81, 0x98, 0xdd, 0x96, - 0x49, 0xbf, 0xe0, 0x19, 0x67, 0x51, 0x14, 0x01, 0xfd, 0x4c, 0xd0, 0xe6, - 0xa0, 0x37, 0x06, 0x62, 0x1a, 0xb4, 0xd6, 0x3a, 0x59, 0x38, 0x05, 0xa0, - 0xb9, 0x50, 0xa0, 0x0b, 0xe5, 0x12, 0xf4, 0x63, 0x63, 0x66, 0x63, 0xf5, - 0xed, 0xf1, 0xc6, 0xc8, 0x46, 0xae, 0x3b, 0xe7, 0x3b, 0xe1, 0xf4, 0x3f, - 0x37, 0xbc, 0xfc, 0xb5, 0x5c, 0x37, 0xc6, 0x52, 0xac, 0x1c, 0x6a, 0x64, - 0x34, 0x6a, 0x22, 0xfb, 0x4c, 0x85, 0x26, 0x7a, 0x31, 0xcb, 0xd3, 0xaa, - 0x60, 0xf5, 0xcc, 0xd3, 0x46, 0x77, 0xd5, 0x68, 0x0f, 0x8d, 0xf9, 0x4e, - 0xa3, 0xf9, 0xe3, 0x1b, 0xc7, 0x9b, 0x5e, 0x4f, 0xec, 0xd4, 0xe8, 0xb8, - 0x40, 0x6f, 0xf4, 0x87, 0x25, 0x8f, 0x24, 0x82, 0x35, 0x22, 0x4a, 0x35, - 0x1a, 0xa3, 0xea, 0x66, 0x67, 0xca, 0x99, 0xe0, 0xbe, 0x17, 0xbe, 0x3b, - 0xd3, 0x79, 0x07, 0x7d, 0x73, 0x33, 0x1b, 0xcb, 0xf5, 0x76, 0x4f, 0x57, - 0x78, 0xae, 0x77, 0xf9, 0x62, 0x2b, 0x0f, 0x7b, 0xda, 0xfb, 0x56, 0x16, - 0xae, 0x34, 0xb2, 0x31, 0x90, 0x3e, 0x3d, 0x1b, 0x9d, 0x66, 0xec, 0x8e, - 0x0d, 0x4f, 0x89, 0x7a, 0xa3, 0x39, 0x34, 0xb6, 0x53, 0x23, 0x3d, 0xa8, - 0x51, 0x1e, 0xde, 0x88, 0xf7, 0x1b, 0x0f, 0xc3, 0x73, 0x77, 0x1a, 0xd7, - 0x93, 0x67, 0xe3, 0x7a, 0xc9, 0xdd, 0x55, 0xa3, 0x27, 0x7d, 0x06, 0x36, - 0x22, 0x1b, 0x05, 0xc4, 0x0c, 0xa5, 0xd4, 0xd7, 0xdf, 0xe4, 0xab, 0xc6, - 0x74, 0x6b, 0xbf, 0x2e, 0xb7, 0xf2, 0xf7, 0x71, 0x94, 0x2b, 0x10, 0xaa, - 0x14, 0x18, 0x58, 0x8c, 0x54, 0xc8, 0xfc, 0x9a, 0xa6, 0x46, 0xa8, 0x8d, - 0xb2, 0xe3, 0xa1, 0x7c, 0x33, 0xd8, 0x6c, 0x88, 0x87, 0x96, 0x9a, 0x9f, - 0x2a, 0xfe, 0xd6, 0x02, 0x16, 0x4a, 0x16, 0xe6, 0x51, 0xbd, 0x94, 0xd2, - 0x5c, 0x85, 0x42, 0xed, 0x52, 0x0e, 0x35, 0x1d, 0x2c, 0xa6, 0x55, 0x77, - 0x43, 0xd7, 0x23, 0xf9, 0x72, 0x0d, 0x0e, 0xf4, 0x48, 0x1e, 0x48, 0x26, - 0x7d, 0xaa, 0xdc, 0x39, 0xe0, 0x3d, 0x22, 0x32, 0xd3, 0x1f, 0x71, 0xa6, - 0xd8, 0x4b, 0x1b, 0x2c, 0xa3, 0xbf, 0xd6, 0x4c, 0xbe, 0xcc, 0xfd, 0x19, - 0xe2, 0x52, 0xa6, 0x9b, 0x5b, 0x96, 0x07, 0x78, 0x65, 0x01, 0x8b, 0x12, - 0x2a, 0x4b, 0x61, 0x31, 0x7f, 0x66, 0x17, 0xe3, 0xc3, 0x06, 0x1b, 0x63, - 0x16, 0x25, 0x03, 0xd6, 0x1e, 0x99, 0xfe, 0xde, 0xe5, 0xaf, 0xbe, 0x8d, - 0x09, 0xc5, 0x29, 0xf7, 0x18, 0x73, 0xba, 0xe0, 0x5d, 0x57, 0x25, 0xbf, - 0x90, 0xbd, 0x07, 0x9c, 0x08, 0x55, 0x02, 0x92, 0x45, 0xb4, 0xec, 0x39, - 0x4c, 0x11, 0x12, 0xb9, 0xa9, 0xaa, 0x1f, 0xb9, 0xe9, 0x8b, 0x52, 0xfc, - 0x69, 0x16, 0x7f, 0xeb, 0x88, 0xab, 0x8d, 0xec, 0xd2, 0xd8, 0xf3, 0x1b, - 0x17, 0x58, 0x0c, 0xaa, 0x32, 0x7d, 0x3e, 0x90, 0xe8, 0x05, 0xce, 0x07, - 0xcd, 0xd0, 0x61, 0xe1, 0x55, 0x79, 0x74, 0x85, 0x1b, 0x57, 0xe8, 0x4a, - 0x0d, 0xb0, 0xea, 0x8d, 0x56, 0x27, 0x1a, 0x2d, 0x35, 0x8e, 0xe8, 0x8a, - 0xcb, 0xab, 0x33, 0x30, 0x39, 0xb7, 0x2a, 0xab, 0xda, 0xe3, 0x42, 0x98, - 0x08, 0xf3, 0x52, 0x1a, 0xd7, 0x9e, 0x5e, 0x64, 0xc3, 0x87, 0x79, 0x3c, - 0x29, 0x56, 0x75, 0xef, 0x0b, 0xaa, 0xac, 0x01, 0x96, 0xb1, 0xfd, 0x84, - 0x89, 0xeb, 0xf2, 0xc0, 0x9d, 0x48, 0xa8, 0xc7, 0x97, 0xfb, 0x47, 0x18, - 0xe9, 0x7e, 0x00, 0xbc, 0x67, 0xd2, 0xeb, 0x2d, 0x74, 0x91, 0xbd, 0x59, - 0xa6, 0xe5, 0x39, 0xd2, 0xf1, 0x6d, 0x46, 0x03, 0xbb, 0x44, 0x74, 0x69, - 0x6e, 0x75, 0x29, 0xec, 0x52, 0xaa, 0xca, 0xde, 0x0e, 0x29, 0x82, 0xef, - 0x5d, 0xfe, 0x85, 0xba, 0x3c, 0x80, 0x5f, 0x2e, 0xbb, 0x38, 0xd7, 0x1d, - 0x19, 0xf3, 0x25, 0x19, 0x33, 0x5e, 0xf0, 0xee, 0xc0, 0x2e, 0x09, 0xe7, - 0x68, 0x7b, 0x25, 0x01, 0xa9, 0xbe, 0xb2, 0x4b, 0x85, 0x44, 0xc3, 0x1b, - 0x36, 0xe3, 0x83, 0x1c, 0x5d, 0x89, 0x5a, 0x55, 0x41, 0xb8, 0x2e, 0x57, - 0x02, 0x4b, 0x99, 0x76, 0x0b, 0x66, 0x3c, 0x8b, 0xfd, 0x74, 0xd6, 0x0c, - 0xe3, 0x49, 0x79, 0x64, 0xea, 0x95, 0x6f, 0xf5, 0x81, 0x6b, 0x37, 0xfb, - 0x69, 0x84, 0x8c, 0x13, 0xce, 0xa8, 0xc4, 0x92, 0x0a, 0x0b, 0x4b, 0xa8, - 0xb3, 0xf7, 0x0f, 0x18, 0xe4, 0xba, 0x14, 0x55, 0x06, 0xa6, 0x61, 0xf1, - 0xce, 0x37, 0xec, 0xb4, 0x1d, 0x0d, 0xf6, 0x33, 0x98, 0x56, 0x7b, 0xf1, - 0x98, 0x41, 0x7f, 0x71, 0x42, 0xfc, 0x49, 0x83, 0xbe, 0xd1, 0x27, 0x7f, - 0xbe, 0xcb, 0xd7, 0xfa, 0x6c, 0x75, 0xb1, 0xff, 0x1a, 0xff, 0x28, 0xf4, - 0xf3, 0xd6, 0x3f, 0xf6, 0x1f, 0x7f, 0xfe, 0x4a, 0xff, 0x15, 0xff, 0x21, - 0x1f, 0x7a, 0xd3, 0xb2, 0x23, 0x63, 0xd3, 0xd8, 0xb9, 0x24, 0x5d, 0x54, - 0xe3, 0x59, 0xe8, 0xba, 0x1c, 0x02, 0x7c, 0x2b, 0xcf, 0x79, 0xaf, 0x8a, - 0x5f, 0x1f, 0x60, 0x09, 0x7b, 0x30, 0x75, 0xa1, 0x6d, 0xef, 0xef, 0x2b, - 0x72, 0x93, 0xb8, 0xfa, 0xd3, 0x01, 0xfd, 0x72, 0xc2, 0x61, 0x2a, 0x8c, - 0xa2, 0x77, 0xf9, 0x81, 0xb7, 0x7b, 0xca, 0xf3, 0x7f, 0x80, 0x89, 0x20, - 0xb5, 0xff, 0x93, 0x2e, 0x2c, 0xc2, 0xe5, 0xf7, 0x18, 0xc8, 0x07, 0xce, - 0xda, 0x8c, 0x06, 0xf7, 0x64, 0x06, 0x96, 0xff, 0x07, 0xfa, 0xda, 0x36, - 0xc9, 0xe6, 0x1c, 0xa4, 0x59, 0xb9, 0xf8, 0xe5, 0xca, 0x97, 0xc8, 0x87, - 0x47, 0x00, 0xdc, 0x79, 0x0a, 0x5f, 0x80, 0xa6, 0xee, 0x89, 0x2b, 0xda, - 0x83, 0xcb, 0x98, 0x6a, 0x5a, 0xc7, 0x36, 0xcc, 0x4b, 0x45, 0xdc, 0xcf, - 0xec, 0xff, 0x24, 0x34, 0x67, 0x4f, 0xcc, 0xa3, 0xea, 0x33, 0xf7, 0xba, - 0x06, 0x53, 0xdc, 0x54, 0xe2, 0xa6, 0x93, 0x41, 0x1e, 0x89, 0x86, 0x44, - 0x07, 0xdf, 0xea, 0xa2, 0x02, 0x49, 0x1c, 0x41, 0x62, 0x1b, 0x36, 0x93, - 0xe8, 0xf9, 0xf0, 0xfc, 0x5b, 0xf7, 0x95, 0xd1, 0x0c, 0x44, 0x13, 0x88, - 0x26, 0x12, 0x4d, 0x22, 0x1a, 0x5a, 0xbe, 0xad, 0x96, 0x98, 0xcf, 0x0c, - 0xac, 0x1b, 0x03, 0xbd, 0x22, 0x1f, 0x3e, 0x27, 0x1f, 0xc6, 0x1a, 0xfc, - 0x29, 0x97, 0x91, 0xbc, 0x0f, 0xb4, 0x81, 0xf5, 0xc9, 0x0e, 0xe9, 0xfb, - 0x0b, 0x4d, 0xde, 0x9f, 0xa5, 0x21, 0xb3, 0x7a, 0x5a, 0xcc, 0xb7, 0xd6, - 0x67, 0x3b, 0xc4, 0xe3, 0xf6, 0x07, 0xbb, 0xfd, 0xe1, 0x8e, 0x85, 0x0d, - 0x3c, 0xdd, 0xf1, 0x8a, 0xd6, 0xcd, 0x73, 0xda, 0x41, 0x09, 0xef, 0x99, - 0x58, 0xe9, 0x91, 0xcf, 0x8c, 0x82, 0xfd, 0x54, 0xf0, 0xf0, 0xd8, 0x13, - 0x08, 0xf4, 0xd6, 0x63, 0xbf, 0x16, 0xfb, 0x65, 0xaf, 0x22, 0xa5, 0x36, - 0x93, 0x85, 0xe8, 0x22, 0xec, 0xf2, 0xbd, 0x63, 0x73, 0x48, 0xee, 0x86, - 0xa5, 0x32, 0x64, 0x22, 0xd9, 0xbe, 0x37, 0xfe, 0x59, 0x8d, 0xbf, 0xec, - 0xe7, 0x2f, 0x42, 0x9f, 0xef, 0x8d, 0x3f, 0xab, 0xf1, 0xfd, 0xf3, 0xcd, - 0x3e, 0xa3, 0xa9, 0xf9, 0x16, 0x86, 0xa1, 0xbd, 0x92, 0xda, 0xec, 0x8c, - 0x00, 0x03, 0x6f, 0x34, 0xdb, 0xe2, 0x7b, 0xb7, 0x7f, 0x70, 0xb7, 0x1e, - 0x41, 0x6b, 0x7b, 0x14, 0x54, 0xbe, 0x94, 0x9a, 0xd9, 0x62, 0x15, 0x4e, - 0x11, 0x31, 0x16, 0x7d, 0x5d, 0xcd, 0x1b, 0xf9, 0xf3, 0x52, 0xfe, 0x3c, - 0xdb, 0xff, 0xd7, 0xb7, 0xaa, 0xea, 0x3b, 0x57, 0x35, 0x1b, 0xf9, 0x5a, - 0xfe, 0x3c, 0x29, 0xc5, 0xca, 0xfe, 0x34, 0x08, 0x23, 0x0e, 0x83, 0xbe, - 0x1d, 0x59, 0xcd, 0x13, 0x0d, 0xcc, 0x79, 0xdd, 0xe7, 0xd6, 0x5c, 0xf8, - 0x02, 0xcb, 0x65, 0xa3, 0x3b, 0x24, 0x8e, 0x4f, 0xa9, 0x64, 0x2f, 0x0f, - 0x18, 0x0e, 0x8d, 0xe9, 0xb2, 0x11, 0x6e, 0x25, 0xd6, 0xbd, 0x61, 0x77, - 0x4f, 0xb5, 0x61, 0xa9, 0x76, 0xfd, 0x83, 0xc6, 0x7a, 0xd9, 0x68, 0x0f, - 0x8d, 0x45, 0x1b, 0xdd, 0xa1, 0x31, 0xd3, 0xee, 0xf6, 0x46, 0xd6, 0xc6, - 0x70, 0xd5, 0x08, 0x66, 0x2c, 0x5f, 0x36, 0xc6, 0x06, 0x84, 0xf6, 0x86, - 0x4d, 0x25, 0x5d, 0x35, 0xce, 0xb3, 0xdc, 0x5a, 0x38, 0x77, 0x17, 0x8d, - 0x45, 0x1b, 0xdd, 0x55, 0xa3, 0x47, 0xea, 0xb6, 0x36, 0xcc, 0xa5, 0x38, - 0x36, 0x02, 0x77, 0xc7, 0x1b, 0xf1, 0xd0, 0x18, 0x2f, 0x1b, 0x09, 0x0e, - 0x5d, 0x6d, 0x70, 0x5b, 0xbd, 0x51, 0x0e, 0x8d, 0xf5, 0x01, 0x8d, 0xeb, - 0x51, 0xde, 0x28, 0xd7, 0x8d, 0xf1, 0x7e, 0x63, 0xba, 0xd3, 0x78, 0x83, - 0x95, 0xd6, 0xc6, 0xcf, 0xcc, 0x68, 0xbf, 0x60, 0xe3, 0xc9, 0xa1, 0xa1, - 0xa4, 0x2b, 0xed, 0xa1, 0xb1, 0x72, 0x0b, 0xae, 0x1b, 0x1b, 0xf7, 0xeb, - 0xba, 0x81, 0x1d, 0x8c, 0x87, 0xc6, 0x69, 0xdf, 0xc3, 0xa1, 0x31, 0x91, - 0x6d, 0xae, 0x1b, 0xf9, 0x92, 0xc7, 0xfa, 0x2b, 0xf6, 0xeb, 0x0e, 0x8d, - 0xe5, 0x92, 0x69, 0xdb, 0x2b, 0x7e, 0x3e, 0xb2, 0xfa, 0x99, 0xbf, 0x52, - 0x6d, 0x9c, 0x45, 0x26, 0x5e, 0x89, 0xd5, 0x51, 0xe2, 0xa6, 0xcb, 0xc6, - 0x51, 0x3c, 0x4f, 0x92, 0xdb, 0x5f, 0x49, 0xf7, 0x51, 0xf0, 0x3f, 0x5b, - 0x31, 0x72, 0x2c, 0x1d, 0xb9, 0x5b, 0x7d, 0x91, 0xc8, 0x45, 0xde, 0xf8, - 0x4b, 0x06, 0x65, 0xbf, 0x0f, 0xfa, 0x3e, 0xe8, 0x6f, 0x14, 0xdb, 0x8f, - 0x36, 0xbf, 0xd6, 0x02, 0x17, 0x78, 0x30, 0x75, 0x1b, 0x10, 0xb5, 0x4a, - 0xfa, 0xeb, 0xad, 0x28, 0xe4, 0x15, 0x35, 0x2a, 0xab, 0x60, 0x91, 0xc1, - 0x68, 0x33, 0x15, 0xa3, 0x61, 0xb2, 0x85, 0xc8, 0x1b, 0x2f, 0xb2, 0xad, - 0x53, 0xde, 0x21, 0x32, 0x5b, 0x53, 0xce, 0xa0, 0xc5, 0x16, 0x27, 0xe1, - 0x92, 0xcd, 0x6e, 0x67, 0x21, 0x94, 0x86, 0x1a, 0x5b, 0xb1, 0x25, 0xb3, - 0x3e, 0x26, 0x6b, 0x0a, 0xe2, 0x6c, 0xb7, 0x13, 0xc4, 0x20, 0x8c, 0x20, - 0x06, 0xdd, 0x04, 0xf1, 0x66, 0x4d, 0x8d, 0xc3, 0xd8, 0xed, 0x14, 0xf1, - 0x68, 0xb7, 0x7b, 0x51, 0x3c, 0xa0, 0x24, 0x88, 0x11, 0x64, 0x12, 0xc4, - 0x88, 0xb7, 0x0a, 0x62, 0x44, 0x91, 0x04, 0xf1, 0x66, 0xb7, 0x13, 0xc4, - 0x8c, 0x33, 0x0e, 0xc5, 0x63, 0x8f, 0x4f, 0x0d, 0xdb, 0x00, 0xc4, 0xb3, - 0xdd, 0xee, 0x75, 0xf1, 0x12, 0x0f, 0x41, 0xbc, 0xa1, 0xd4, 0x3b, 0x15, - 0x56, 0x46, 0xe8, 0xab, 0xfd, 0x46, 0xbd, 0x9d, 0x22, 0x9e, 0x4c, 0x85, - 0x0d, 0x86, 0x2d, 0x02, 0xf1, 0x62, 0xb7, 0x13, 0xc4, 0x78, 0xc6, 0xea, - 0x75, 0xa1, 0x92, 0x35, 0xc3, 0xcc, 0x6e, 0xb7, 0x23, 0x7e, 0x85, 0x84, - 0xe7, 0x8e, 0xf8, 0x6d, 0x91, 0xe4, 0xec, 0x47, 0x41, 0xfc, 0xab, 0x3e, - 0xc2, 0xf1, 0x9b, 0x20, 0xfe, 0xa8, 0xa7, 0xdc, 0x26, 0x88, 0x7f, 0xb3, - 0x4a, 0x60, 0xf9, 0xfd, 0xe2, 0x2d, 0x69, 0x8c, 0xf7, 0xb9, 0x20, 0x8e, - 0x5a, 0x2b, 0xf2, 0x4c, 0x10, 0x3f, 0xd3, 0x38, 0xd2, 0x4b, 0x41, 0xfc, - 0xb2, 0x48, 0xb1, 0xc3, 0x1b, 0x41, 0xfc, 0x46, 0x9f, 0x6c, 0x79, 0x2f, - 0x88, 0xdf, 0xa9, 0x09, 0xaa, 0xbf, 0x64, 0xbc, 0xe8, 0x71, 0xb4, 0xe8, - 0xef, 0x4b, 0xa7, 0x62, 0x0f, 0xf4, 0xbc, 0x10, 0x4b, 0x62, 0xd4, 0xe7, - 0x8b, 0x5e, 0xcb, 0x6b, 0x3c, 0xa6, 0x46, 0x1e, 0x77, 0x7a, 0x57, 0xf4, - 0x87, 0x0c, 0xa3, 0x0e, 0xda, 0xfb, 0x48, 0xa9, 0x86, 0x0e, 0x7a, 0x5d, - 0xe4, 0x11, 0x70, 0x1d, 0x34, 0xeb, 0x49, 0xa8, 0x83, 0x96, 0x28, 0x76, - 0xea, 0x2c, 0xe9, 0xe6, 0x9d, 0x0f, 0x27, 0x7d, 0x8c, 0xe7, 0x8d, 0xf0, - 0x61, 0xee, 0xe4, 0xbb, 0xf7, 0xc2, 0x87, 0x73, 0x2b, 0xdf, 0x7d, 0xb0, - 0xa0, 0x98, 0xfe, 0x62, 0xb2, 0x1c, 0x48, 0x12, 0x28, 0xeb, 0x65, 0x6d, - 0x39, 0x49, 0x14, 0xad, 0x93, 0xb5, 0xc9, 0xaf, 0x26, 0x46, 0x89, 0x65, - 0x3f, 0x2b, 0x4b, 0xd0, 0x48, 0x99, 0x98, 0xbb, 0xeb, 0x20, 0x49, 0xe6, - 0xac, 0x88, 0x3b, 0x79, 0x26, 0x67, 0x56, 0xc4, 0xad, 0x18, 0xc6, 0xb3, - 0x15, 0xb8, 0xcb, 0x17, 0x8b, 0x21, 0x4e, 0xf6, 0x85, 0x20, 0x8e, 0xf6, - 0x85, 0x20, 0x1e, 0xec, 0x0b, 0x41, 0xac, 0x73, 0x6c, 0x14, 0xb1, 0xce, - 0x71, 0x54, 0xc4, 0x3a, 0xc7, 0x49, 0x11, 0xeb, 0x1c, 0xb3, 0x21, 0x16, - 0x3a, 0xcc, 0x86, 0x58, 0x9e, 0x8a, 0x9a, 0x3b, 0x45, 0x2c, 0x0f, 0x69, - 0x49, 0x9c, 0x3e, 0xca, 0x6c, 0xde, 0xe9, 0x09, 0xfe, 0x4c, 0x32, 0xe2, - 0x8b, 0x9a, 0x1a, 0x2f, 0x05, 0xb0, 0x69, 0x80, 0xef, 0x8d, 0x2e, 0x33, - 0xc9, 0x83, 0x81, 0xef, 0xd5, 0xd6, 0x78, 0x2e, 0x75, 0x73, 0x3b, 0xe2, - 0x1d, 0xf0, 0x4a, 0xc8, 0xb5, 0x6a, 0xe9, 0xce, 0x5b, 0x21, 0x97, 0x3c, - 0xc6, 0xa5, 0xcc, 0xa8, 0x88, 0x35, 0x31, 0x3f, 0x37, 0xf6, 0xf3, 0xdf, - 0xc5, 0xa2, 0x84, 0x2f, 0x2d, 0xa8, 0xb8, 0x02, 0x71, 0x30, 0x63, 0xe5, - 0x7d, 0x41, 0x95, 0xaa, 0x21, 0x16, 0x5e, 0x6b, 0x0c, 0xb1, 0x60, 0x1b, - 0x0d, 0xb1, 0x16, 0xfe, 0x1a, 0xe2, 0x26, 0x99, 0xed, 0xf2, 0xcc, 0x22, - 0x93, 0x19, 0x88, 0x83, 0x45, 0x96, 0xdf, 0x58, 0xc4, 0x79, 0x01, 0xe2, - 0xde, 0x22, 0xd0, 0x1f, 0x50, 0x9a, 0x04, 0xc4, 0x30, 0x6f, 0xf4, 0xc1, - 0xb3, 0x64, 0x5f, 0x45, 0x0b, 0x6f, 0x8e, 0x40, 0x1c, 0x8a, 0x7e, 0xf5, - 0xd2, 0x1c, 0xa0, 0x0c, 0xc4, 0x9d, 0xb9, 0x41, 0xef, 0xcd, 0x02, 0x9a, - 0x81, 0xb8, 0x31, 0x37, 0x69, 0x35, 0xcf, 0x48, 0x7a, 0x6d, 0x05, 0x0f, - 0x6a, 0xb5, 0x52, 0x6d, 0x25, 0xbc, 0xbd, 0x99, 0x15, 0xa9, 0xbf, 0xd5, - 0x62, 0x62, 0xa8, 0x75, 0x84, 0x5a, 0x38, 0x65, 0xf6, 0x9f, 0x05, 0x55, - 0xd5, 0x48, 0xca, 0x16, 0x77, 0x16, 0xa1, 0x41, 0xc5, 0xfc, 0xb8, 0x7f, - 0x39, 0x5b, 0x58, 0x7a, 0x6a, 0xe4, 0x19, 0x37, 0x0d, 0x55, 0xcb, 0x83, - 0x58, 0x2b, 0x11, 0xb7, 0x30, 0xb0, 0x4c, 0x04, 0x1b, 0x22, 0x4e, 0x78, - 0x3a, 0x4b, 0x21, 0x23, 0x11, 0x0f, 0x5a, 0xb0, 0xbf, 0xf1, 0x59, 0x06, - 0x57, 0x7d, 0x7e, 0x0a, 0xe0, 0xd4, 0xd0, 0x2f, 0xda, 0x02, 0x15, 0x96, - 0x0c, 0xa5, 0x1d, 0x13, 0x23, 0x3a, 0x40, 0xcd, 0xd5, 0x98, 0x38, 0x3b, - 0x64, 0x3e, 0x92, 0x8b, 0x0e, 0x6e, 0x42, 0x4d, 0xe8, 0x30, 0xd7, 0x57, - 0xd6, 0x58, 0xe4, 0x7d, 0x44, 0x87, 0xb9, 0x46, 0xeb, 0xb5, 0x83, 0x57, - 0x7a, 0x65, 0x74, 0x58, 0x6a, 0x2a, 0xc6, 0x3a, 0x4c, 0xe8, 0xb0, 0x54, - 0x2b, 0x2d, 0x00, 0xa5, 0x75, 0xc0, 0x23, 0x69, 0x46, 0x11, 0x52, 0xd4, - 0x50, 0xf6, 0xf8, 0x02, 0x29, 0x0c, 0x76, 0x98, 0xd0, 0xa1, 0xbe, 0x79, - 0x07, 0x1d, 0x26, 0x74, 0xe0, 0x03, 0x08, 0xf5, 0x67, 0x03, 0xd0, 0x21, - 0xa3, 0x43, 0x7d, 0xfd, 0x33, 0x3a, 0x64, 0x74, 0x60, 0xae, 0xcc, 0xdf, - 0x9d, 0x35, 0xa1, 0x03, 0x7f, 0xd7, 0xee, 0xfa, 0xcd, 0xb9, 0xda, 0xe1, - 0x2d, 0x5e, 0x18, 0xfd, 0x11, 0x71, 0x7b, 0x11, 0x65, 0xed, 0xf0, 0x0c, - 0xef, 0x98, 0x78, 0x83, 0x12, 0x86, 0x05, 0x25, 0x0f, 0xbb, 0xae, 0x5b, - 0xb4, 0xc3, 0x53, 0x3c, 0x4b, 0xf7, 0x1a, 0xef, 0x7e, 0xda, 0xd5, 0x86, - 0x3d, 0x6c, 0x37, 0x20, 0x6f, 0xf0, 0xc4, 0x0e, 0x03, 0xd1, 0x52, 0xea, - 0x87, 0xef, 0xc3, 0xd4, 0x33, 0x17, 0xf5, 0xa3, 0x1d, 0x46, 0xfc, 0xf8, - 0x49, 0x8e, 0xf6, 0xa3, 0x5b, 0x4b, 0x6f, 0xbf, 0x5d, 0x2b, 0x0e, 0xe3, - 0x2b, 0xed, 0x10, 0x25, 0xfd, 0x51, 0xbc, 0x9e, 0x86, 0x05, 0x36, 0x57, - 0x6b, 0x61, 0xcd, 0x1f, 0x6b, 0xe7, 0x36, 0xe6, 0x83, 0xc6, 0x2b, 0x32, - 0x45, 0x74, 0x00, 0xca, 0x33, 0x81, 0x17, 0xdf, 0x01, 0xa0, 0x1c, 0x1b, - 0x76, 0x08, 0xe8, 0x70, 0xda, 0xbb, 0x11, 0x28, 0x21, 0x61, 0x14, 0x24, - 0x8a, 0xce, 0x91, 0x2d, 0xbc, 0xe8, 0x89, 0x1d, 0x02, 0x3a, 0xf4, 0xe8, - 0xe0, 0x1c, 0x17, 0xd1, 0x81, 0x69, 0xc2, 0x2b, 0x5e, 0x65, 0x0e, 0xca, - 0xd3, 0x4a, 0xec, 0x10, 0xd0, 0x81, 0x62, 0xd0, 0xb0, 0x43, 0x44, 0x87, - 0x01, 0x1d, 0x2e, 0x05, 0x68, 0xac, 0xe5, 0x46, 0x5e, 0xef, 0xc8, 0x0e, - 0x01, 0x1d, 0x28, 0x9b, 0x0d, 0x3b, 0xc4, 0x52, 0x8d, 0x16, 0x98, 0x81, - 0x6e, 0x01, 0x6a, 0x87, 0x01, 0x1d, 0x3a, 0x64, 0xc9, 0x2c, 0x8f, 0x68, - 0x6a, 0x9c, 0xda, 0xa0, 0x39, 0x08, 0xb7, 0xcb, 0xe8, 0x29, 0xbb, 0x4a, - 0xe3, 0xa2, 0x4a, 0x23, 0xd5, 0xd1, 0x61, 0x03, 0x8a, 0xd7, 0x77, 0x7a, - 0x3a, 0xd0, 0xc5, 0xc5, 0xdf, 0x42, 0xe9, 0x2c, 0x53, 0x8b, 0xb4, 0x44, - 0x10, 0x54, 0x6c, 0xd6, 0x1e, 0x11, 0x2a, 0xe1, 0xd0, 0x95, 0xde, 0xf6, - 0x4a, 0x23, 0xf1, 0xec, 0x24, 0x26, 0x26, 0xdb, 0x12, 0x43, 0x0d, 0x91, - 0xfa, 0x26, 0x14, 0x3c, 0x3c, 0xfa, 0x23, 0x49, 0xfe, 0x86, 0xca, 0xcb, - 0xf3, 0x79, 0x9e, 0xe1, 0xfb, 0x8d, 0xb1, 0x86, 0xea, 0x1c, 0x26, 0x2e, - 0xfd, 0x39, 0x6d, 0xb7, 0x57, 0x87, 0xac, 0x31, 0xb5, 0x60, 0xcd, 0x2c, - 0x73, 0x3b, 0x2f, 0x83, 0x16, 0xe9, 0x92, 0x86, 0x23, 0xf9, 0xed, 0x3b, - 0xa2, 0x7f, 0x24, 0xa2, 0x2f, 0xe3, 0x23, 0x67, 0xc8, 0xf7, 0x34, 0xf9, - 0xbd, 0xf4, 0xa1, 0x86, 0x36, 0x12, 0x39, 0x3b, 0xd0, 0xd4, 0x67, 0x09, - 0x45, 0x31, 0xff, 0x2f, 0x1e, 0x44, 0x64, 0x2a, 0x28, 0xbc, 0x90, 0x73, - 0x42, 0xa3, 0xba, 0x72, 0x92, 0xe8, 0xc1, 0x34, 0x33, 0xb5, 0xec, 0x3f, - 0x47, 0xe7, 0x25, 0x1d, 0x5e, 0xe4, 0xb1, 0x56, 0xa1, 0xf5, 0x42, 0x10, - 0xd7, 0xf7, 0x7e, 0x88, 0x55, 0xe9, 0x0f, 0x6c, 0x50, 0x1f, 0x1f, 0xe2, - 0x76, 0x91, 0x0d, 0x5a, 0x0b, 0xb4, 0x68, 0xa0, 0x62, 0x72, 0x03, 0x50, - 0x63, 0x1f, 0xcb, 0x33, 0x93, 0xa8, 0x3c, 0xbd, 0xbd, 0x54, 0xc5, 0x0f, - 0x0f, 0x4c, 0xcc, 0x7f, 0xbd, 0x64, 0x62, 0x3d, 0x0a, 0xb5, 0x8a, 0x3f, - 0xc5, 0xc2, 0xd7, 0xf3, 0xd7, 0x2a, 0x51, 0x2e, 0xd8, 0xeb, 0x47, 0x67, - 0x20, 0xf1, 0xf7, 0xa7, 0x6f, 0x81, 0xdf, 0xf0, 0x04, 0xfb, 0x19, 0xe6, - 0x9d, 0x17, 0xac, 0x7e, 0xe0, 0xbc, 0x5e, 0x16, 0x44, 0x47, 0x53, 0x29, - 0x97, 0xa5, 0xb2, 0xaf, 0xb0, 0x55, 0x5e, 0x44, 0xfb, 0x2b, 0x0b, 0x58, - 0x9e, 0x57, 0x73, 0xc8, 0x2b, 0x73, 0x78, 0x62, 0x78, 0x00, 0x73, 0xa9, - 0xf6, 0x8f, 0x9f, 0x42, 0x5e, 0x80, 0xe2, 0x55, 0x2b, 0x7f, 0x2c, 0x12, - 0x3f, 0x06, 0xaf, 0x96, 0xe3, 0x0a, 0x34, 0x62, 0x39, 0xdd, 0x99, 0x26, - 0x3d, 0x69, 0x52, 0xea, 0x8f, 0xb0, 0xf9, 0xaf, 0xb2, 0xf9, 0x23, 0x4a, - 0x4f, 0x71, 0xf5, 0x32, 0xdf, 0x9f, 0x70, 0xf5, 0xdd, 0x51, 0x63, 0x47, - 0x00, 0xdc, 0xe2, 0x09, 0x48, 0xfc, 0x41, 0x03, 0x5a, 0x58, 0x5e, 0xb9, - 0x5f, 0x6d, 0x09, 0x2f, 0x76, 0x4a, 0x58, 0x7c, 0x87, 0xb5, 0x9b, 0x13, - 0x60, 0xcc, 0xa6, 0xf1, 0x07, 0xc6, 0x51, 0x6a, 0xe5, 0x8c, 0x97, 0xdb, - 0x78, 0x71, 0x4d, 0x02, 0x9f, 0x7a, 0xfd, 0xcd, 0x77, 0x24, 0x7f, 0x65, - 0x24, 0xd6, 0xfd, 0x6f, 0x6d, 0xea, 0xac, 0x97, 0xa6, 0x8e, 0xfd, 0x02, - 0xcc, 0xa7, 0x4c, 0x9d, 0xf0, 0xdd, 0xd4, 0xf9, 0x8e, 0xe8, 0xdb, 0x21, - 0xfa, 0x3a, 0xa6, 0x4e, 0xfb, 0x17, 0x34, 0x75, 0xd6, 0x07, 0x98, 0x3a, - 0x17, 0x29, 0xca, 0x08, 0xaa, 0x9c, 0x4c, 0x9d, 0xd5, 0x75, 0x4d, 0x43, - 0x10, 0x35, 0x1b, 0xf4, 0xd6, 0x8e, 0x1e, 0xfa, 0x2a, 0x40, 0xd9, 0x09, - 0x8a, 0x91, 0x6a, 0x0b, 0x9d, 0x5c, 0xa9, 0x45, 0x76, 0x1a, 0x88, 0xa9, - 0xa3, 0x6e, 0x6c, 0xa8, 0x13, 0x5d, 0xed, 0x35, 0xfc, 0x79, 0x2c, 0xe9, - 0xd4, 0xb0, 0xd3, 0xc8, 0x4e, 0x23, 0x3b, 0x4d, 0xec, 0x94, 0xd9, 0x89, - 0x8d, 0xc8, 0x37, 0xa4, 0x0c, 0x54, 0xaa, 0x1d, 0x50, 0x37, 0xcd, 0xff, - 0x63, 0xe3, 0x7f, 0xb2, 0xd1, 0x55, 0x67, 0xb5, 0xb9, 0x24, 0x51, 0xcd, - 0xb5, 0xd2, 0xed, 0x66, 0xdc, 0xac, 0x54, 0xdf, 0xfe, 0x41, 0x0f, 0x9d, - 0x7f, 0xe6, 0x8d, 0x02, 0x40, 0x74, 0x68, 0xe0, 0x05, 0xb5, 0xbc, 0x61, - 0xa6, 0x22, 0xcf, 0xdc, 0x53, 0x7f, 0xd0, 0xf7, 0x21, 0x0f, 0xa6, 0x7f, - 0xb6, 0xd1, 0x1c, 0x12, 0x8f, 0x7f, 0x5c, 0x63, 0xb9, 0xd3, 0x78, 0xc8, - 0x0c, 0x8f, 0xeb, 0x3a, 0x2d, 0xd9, 0x89, 0x10, 0xae, 0x08, 0x45, 0xd2, - 0xf5, 0x27, 0xf2, 0x9e, 0x28, 0x7f, 0xb5, 0x29, 0x5f, 0xf4, 0x40, 0x39, - 0x59, 0x62, 0xbd, 0x62, 0x92, 0x3b, 0x8d, 0xcb, 0xb4, 0xf9, 0x75, 0xc3, - 0xd3, 0xe6, 0x9f, 0x68, 0x4c, 0xda, 0xb8, 0x99, 0x51, 0xf7, 0x46, 0x6e, - 0xb0, 0xf6, 0xeb, 0xc6, 0x75, 0x6a, 0xfd, 0x21, 0xc9, 0xf6, 0x87, 0x64, - 0xdd, 0x1f, 0x93, 0x7e, 0xf7, 0x46, 0x7c, 0x54, 0x42, 0xde, 0x1b, 0x9f, - 0xc8, 0xcc, 0x7f, 0x22, 0x45, 0x7f, 0xdd, 0xb8, 0x16, 0xa2, 0x63, 0xe3, - 0x5e, 0xd2, 0xbe, 0x3d, 0xb0, 0xfa, 0x27, 0xde, 0x9d, 0x50, 0xfc, 0xd8, - 0x69, 0x2c, 0xce, 0x6e, 0x3a, 0xd3, 0x1f, 0x8a, 0x60, 0x96, 0x51, 0xd5, - 0x59, 0x34, 0x06, 0x33, 0x6d, 0xec, 0xee, 0x25, 0x63, 0x7a, 0x4b, 0x3d, - 0x06, 0x03, 0x98, 0x13, 0x07, 0x07, 0x4f, 0x82, 0xd9, 0x0f, 0x02, 0x1c, - 0x16, 0xd9, 0xcf, 0x8a, 0x04, 0x36, 0x0e, 0x60, 0xf0, 0x0e, 0xfc, 0x2f, - 0x52, 0x21, 0xa1, 0x4f, 0x79, 0x2e, 0x4d, 0x22, 0x9b, 0x1b, 0xcb, 0xae, - 0x72, 0xb2, 0xbd, 0x5a, 0x03, 0x1c, 0x4a, 0xd6, 0x95, 0x98, 0x89, 0x17, - 0xf0, 0x8a, 0xfa, 0x96, 0xaf, 0xa8, 0x8f, 0x78, 0x25, 0x4c, 0xaf, 0x2e, - 0xd3, 0x04, 0x79, 0x37, 0xcf, 0x2c, 0xc0, 0x55, 0xfb, 0x05, 0x36, 0xab, - 0xbd, 0xe5, 0xbe, 0xc7, 0x6f, 0x43, 0x37, 0xfc, 0xa5, 0x8f, 0x80, 0x17, - 0xcd, 0x74, 0x7c, 0x11, 0x4e, 0x82, 0x79, 0xfd, 0xef, 0xd5, 0xde, 0xee, - 0x78, 0x82, 0x44, 0x00, 0x7a, 0x9e, 0x3b, 0x24, 0x6a, 0x00, 0xc0, 0xa9, - 0x1c, 0x01, 0xe8, 0x09, 0x48, 0x00, 0x0c, 0xe7, 0x7d, 0x40, 0xd6, 0xd3, - 0xf2, 0x97, 0xc0, 0x75, 0x09, 0x88, 0x00, 0x74, 0xb7, 0x00, 0x1b, 0x01, - 0xf9, 0xcb, 0x00, 0x01, 0x80, 0xf6, 0xcb, 0x01, 0x0d, 0x01, 0xc3, 0x01, - 0x70, 0xb1, 0x96, 0x0b, 0x00, 0x57, 0x7b, 0xb5, 0x7c, 0x7f, 0x4f, 0x16, - 0x49, 0x99, 0x01, 0x58, 0x09, 0x98, 0x00, 0xb8, 0x22, 0xf6, 0x2c, 0xaf, - 0xda, 0xb6, 0xf4, 0x96, 0xa5, 0x4e, 0xa6, 0x00, 0xc9, 0x49, 0x1e, 0x86, - 0x5e, 0x2b, 0x2f, 0x9b, 0x70, 0xcc, 0xb0, 0xbb, 0x4c, 0x90, 0x3e, 0xd2, - 0xfd, 0x4f, 0x88, 0x07, 0xbc, 0x45, 0xcf, 0xdf, 0xd8, 0xf3, 0x79, 0xf1, - 0x08, 0xc5, 0xa4, 0xca, 0x25, 0xc1, 0xf3, 0x78, 0x09, 0x26, 0xe4, 0xaf, - 0xac, 0x1c, 0x7f, 0xb9, 0x22, 0xc3, 0x5c, 0x33, 0xc5, 0x32, 0xc0, 0xdd, - 0x7e, 0x0d, 0xd3, 0xc9, 0xde, 0x21, 0x90, 0x90, 0xe0, 0x0f, 0xc5, 0x7e, - 0xc2, 0x39, 0x14, 0x3e, 0x95, 0x59, 0xcf, 0x07, 0x4f, 0x2a, 0xf8, 0x19, - 0x00, 0x29, 0x9a, 0x5c, 0xee, 0x0c, 0x70, 0x48, 0x05, 0x44, 0x1b, 0x59, - 0x6d, 0xd1, 0x68, 0x1d, 0x6a, 0xb2, 0x49, 0x87, 0x4c, 0x4d, 0x8d, 0x37, - 0xf5, 0xdc, 0x98, 0x58, 0xa9, 0x0c, 0x93, 0x26, 0xe5, 0xc6, 0x4d, 0x91, - 0x3f, 0xf7, 0xb3, 0x55, 0x51, 0x8c, 0x55, 0x9c, 0x30, 0x5b, 0xe5, 0x44, - 0xfa, 0xbd, 0x5d, 0x15, 0x3b, 0x72, 0x57, 0x06, 0xcb, 0x7c, 0x1f, 0xfe, - 0x7d, 0xf8, 0xf7, 0xe1, 0x77, 0x87, 0x97, 0x9a, 0xce, 0xb6, 0x7f, 0x16, - 0x45, 0xe7, 0x99, 0x3d, 0xd3, 0x29, 0xd3, 0x41, 0xa7, 0x9a, 0x82, 0x6a, - 0xa0, 0x54, 0xb6, 0xe6, 0x10, 0xd7, 0xfe, 0x8e, 0xe6, 0x3b, 0x9a, 0x7f, - 0x2d, 0x34, 0x81, 0x68, 0x22, 0xd1, 0x24, 0x36, 0x0a, 0xf0, 0xb5, 0x8c, - 0x34, 0x7a, 0xd2, 0x83, 0x16, 0x03, 0x6c, 0x8a, 0x49, 0x47, 0x3f, 0x63, - 0x80, 0x27, 0xc2, 0x1e, 0xb1, 0xd8, 0x4f, 0xa7, 0x46, 0x70, 0x39, 0xb8, - 0x10, 0x41, 0xcd, 0x8a, 0x8d, 0xa1, 0x1f, 0x73, 0x00, 0x3b, 0x18, 0x04, - 0x5a, 0xfc, 0xa0, 0x66, 0x29, 0x0d, 0x8b, 0x8b, 0x67, 0x92, 0x6d, 0xda, - 0x6c, 0xd0, 0xb4, 0xf0, 0xc0, 0xcf, 0xe1, 0x81, 0x55, 0x34, 0x68, 0x5c, - 0x6c, 0x87, 0xf0, 0x6f, 0x24, 0x39, 0x22, 0xa9, 0xe0, 0xa4, 0x0b, 0xa0, - 0x98, 0xe7, 0xde, 0xab, 0xa1, 0xe1, 0x66, 0x5c, 0x63, 0xbf, 0xcb, 0xe3, - 0xe1, 0x21, 0x35, 0xcc, 0x84, 0x4a, 0xbf, 0x16, 0x94, 0x28, 0xfe, 0xe6, - 0x49, 0x89, 0xc4, 0x74, 0xd9, 0xcb, 0x82, 0xe2, 0xcd, 0x5f, 0x68, 0xc7, - 0x2c, 0x05, 0x95, 0x9e, 0xf6, 0x83, 0x57, 0x72, 0xc7, 0x1f, 0x0b, 0xaa, - 0x12, 0x5f, 0x9b, 0x2a, 0xd4, 0x64, 0xd6, 0xd2, 0xc0, 0xb3, 0xd8, 0x0c, - 0x65, 0xcf, 0xa2, 0x81, 0x9f, 0xb8, 0xb7, 0x73, 0xc4, 0xb6, 0xcb, 0x93, - 0x18, 0xda, 0x49, 0x1c, 0x93, 0x49, 0x51, 0x8e, 0x0c, 0xf2, 0xe5, 0x88, - 0x4d, 0x5d, 0x7a, 0x2c, 0x79, 0x6d, 0xb9, 0x87, 0x0d, 0x4d, 0xc9, 0x29, - 0xc0, 0xea, 0xb2, 0x5f, 0x53, 0x54, 0x38, 0xac, 0xca, 0xcd, 0xa2, 0x50, - 0x32, 0x78, 0x80, 0x87, 0x92, 0x3b, 0xfa, 0x2e, 0x0d, 0xbd, 0x1a, 0xed, - 0xa8, 0x28, 0x7b, 0xa4, 0x91, 0x26, 0xbb, 0x8b, 0xf9, 0x5b, 0xcb, 0xa1, - 0x53, 0xb0, 0x0d, 0x9f, 0xac, 0x27, 0xea, 0x7e, 0xb2, 0xdd, 0x45, 0x7a, - 0x0e, 0xe6, 0xbb, 0xd5, 0x4e, 0x06, 0xee, 0x58, 0xb0, 0xd5, 0xc0, 0xa7, - 0x1b, 0x75, 0x48, 0x0b, 0x83, 0xd5, 0x3b, 0x8d, 0x1a, 0x2c, 0x6b, 0x61, - 0x56, 0x4e, 0x76, 0x73, 0xb3, 0x3e, 0x37, 0x9b, 0x45, 0x0f, 0x5f, 0x4d, - 0x3a, 0x4d, 0xf6, 0x27, 0xc9, 0x32, 0xa4, 0xa7, 0xce, 0x22, 0x98, 0x6f, - 0x68, 0x8b, 0xee, 0xd0, 0x49, 0xe2, 0x04, 0xca, 0x3a, 0xf5, 0xe5, 0xf9, - 0x16, 0x96, 0xeb, 0x2c, 0x75, 0xa5, 0xac, 0x3f, 0xb7, 0x74, 0xde, 0x0c, - 0x65, 0xaf, 0xbc, 0x6a, 0xb2, 0x34, 0xe9, 0x52, 0xe4, 0x2e, 0x1d, 0x62, - 0xfc, 0x5b, 0x43, 0xa9, 0x1a, 0x23, 0xe4, 0x36, 0xf3, 0xd5, 0xfe, 0x4b, - 0x47, 0x69, 0x6f, 0x28, 0xc1, 0x53, 0x42, 0xa7, 0x39, 0x80, 0x67, 0x57, - 0x43, 0xd9, 0x6b, 0x36, 0x74, 0xb2, 0xbb, 0x24, 0xd4, 0x81, 0x2d, 0xec, - 0xb4, 0x19, 0xca, 0x4e, 0x85, 0xce, 0x18, 0x38, 0xd3, 0x93, 0x5e, 0xec, - 0xbe, 0x03, 0xdf, 0xb6, 0xdb, 0x69, 0x95, 0x69, 0xa3, 0x08, 0xec, 0x67, - 0xe7, 0xe5, 0x2e, 0x89, 0x96, 0xb7, 0xa1, 0x6c, 0x55, 0x0b, 0x58, 0x27, - 0xbc, 0xfa, 0x77, 0x10, 0x77, 0x25, 0x1b, 0x82, 0xe7, 0x05, 0x51, 0xd3, - 0xb7, 0xf4, 0xe4, 0x3e, 0xb2, 0x53, 0xa9, 0x8e, 0xa2, 0x1d, 0xfd, 0xa9, - 0x9c, 0x43, 0xab, 0xfd, 0x45, 0xa7, 0xdc, 0x40, 0x43, 0xb9, 0x2f, 0xb6, - 0x99, 0x20, 0x52, 0x26, 0x2f, 0x3a, 0x79, 0x66, 0x48, 0x51, 0xb6, 0x44, - 0xa9, 0x77, 0x99, 0x78, 0x17, 0xef, 0xe4, 0xc2, 0xad, 0x28, 0x15, 0xc1, - 0xc8, 0xbb, 0x64, 0xde, 0xc5, 0x3b, 0x99, 0x8b, 0x17, 0x88, 0xb2, 0x27, - 0x4a, 0xcf, 0x48, 0xc9, 0x5d, 0xbc, 0x93, 0xa1, 0xec, 0x5c, 0x73, 0x10, - 0x65, 0xf5, 0x5a, 0x86, 0x63, 0xa7, 0x86, 0x08, 0x26, 0x22, 0x98, 0x79, - 0x97, 0x9a, 0xf7, 0xf2, 0x4e, 0x23, 0x11, 0x64, 0x22, 0x00, 0xef, 0xc8, - 0xc8, 0x0c, 0x5a, 0x8e, 0xd2, 0x75, 0x84, 0x32, 0x17, 0x04, 0x1b, 0x36, - 0x47, 0x3d, 0xc2, 0x05, 0x5b, 0xa6, 0xc2, 0x9b, 0xe5, 0xcf, 0x07, 0x88, - 0xb4, 0xfe, 0x79, 0x03, 0x05, 0xae, 0x7f, 0x9e, 0xd9, 0x10, 0xfd, 0xb3, - 0x25, 0x1b, 0x32, 0xfb, 0x10, 0xca, 0xd0, 0xcf, 0xc5, 0xea, 0xae, 0xc0, - 0x27, 0x90, 0x73, 0xe1, 0x1e, 0x65, 0xb1, 0x64, 0x7f, 0x66, 0xf8, 0x9b, - 0xfa, 0xe7, 0x05, 0x86, 0xe8, 0x9f, 0xc1, 0xa4, 0xf3, 0x30, 0x04, 0x21, - 0xe6, 0x5c, 0xac, 0xac, 0x72, 0x06, 0x07, 0x4f, 0x16, 0xcf, 0xe3, 0x7b, - 0x9e, 0xa3, 0xfd, 0x31, 0x6e, 0x47, 0xc0, 0x31, 0xa7, 0xc3, 0x90, 0x1f, - 0x4c, 0x6f, 0x1c, 0x86, 0x24, 0xd3, 0x1d, 0x2a, 0x45, 0x2d, 0x82, 0x76, - 0x2a, 0x5b, 0x3d, 0xa2, 0x3a, 0x4a, 0xcb, 0x60, 0x7f, 0xec, 0xa5, 0xd0, - 0xc9, 0xfe, 0xcc, 0x03, 0x0e, 0x2b, 0x1d, 0x12, 0x4d, 0x59, 0xad, 0x3e, - 0x24, 0x9a, 0x9a, 0x31, 0xd1, 0x2d, 0xa6, 0x57, 0x32, 0x86, 0xd8, 0x6f, - 0x70, 0x04, 0x4b, 0x51, 0xac, 0xaa, 0x39, 0x92, 0x85, 0xa2, 0xe4, 0xec, - 0xd2, 0x97, 0x4a, 0xb7, 0x05, 0x5a, 0xa6, 0x37, 0x35, 0xaa, 0xba, 0x47, - 0x87, 0x04, 0x8b, 0x56, 0xad, 0x1c, 0x22, 0x2a, 0x68, 0x3e, 0x0e, 0x91, - 0xc2, 0x09, 0x0b, 0x55, 0xf4, 0x50, 0x4b, 0xb1, 0x40, 0xf5, 0x44, 0xd5, - 0xd2, 0x18, 0x6b, 0xba, 0xdb, 0xc6, 0x76, 0xaa, 0xd1, 0xdf, 0x9a, 0x5e, - 0xb2, 0x21, 0xcf, 0x65, 0x88, 0xe9, 0xb7, 0xb2, 0xea, 0x10, 0x89, 0x76, - 0x65, 0x29, 0xf6, 0x96, 0x19, 0x4a, 0x42, 0x7e, 0x94, 0x7a, 0x70, 0x5d, - 0x54, 0xaf, 0xe7, 0x47, 0x34, 0xdd, 0x15, 0xe4, 0x54, 0x59, 0xd3, 0xa6, - 0x74, 0x48, 0x56, 0xb3, 0xac, 0x74, 0x68, 0xf5, 0x70, 0x79, 0x2a, 0x43, - 0x40, 0xa8, 0x2d, 0xc8, 0x10, 0xa9, 0xcc, 0x5d, 0xf5, 0x47, 0x1d, 0x1a, - 0x4b, 0xf9, 0xcc, 0x52, 0xee, 0xbd, 0x76, 0x16, 0xf3, 0xdd, 0x69, 0xfb, - 0xc4, 0x36, 0x48, 0x70, 0x88, 0x0a, 0x53, 0xbd, 0x36, 0x68, 0x75, 0x76, - 0x34, 0x6d, 0xa7, 0x9b, 0x3e, 0x69, 0x21, 0x36, 0x36, 0xbd, 0x13, 0x88, - 0xd6, 0x0b, 0xfe, 0xa0, 0x15, 0xdd, 0x32, 0xfd, 0x5e, 0xdf, 0x8f, 0x10, - 0x84, 0x0d, 0x46, 0x59, 0xdc, 0x3e, 0x24, 0xd9, 0x0f, 0x87, 0xec, 0x08, - 0xd3, 0xd6, 0x9a, 0x0a, 0x54, 0x6e, 0xdc, 0x0f, 0x48, 0x55, 0x8c, 0xca, - 0x8d, 0x39, 0x98, 0x26, 0x54, 0x6e, 0x1c, 0x93, 0xbd, 0xb3, 0x3c, 0x4a, - 0x5d, 0x7a, 0x2b, 0x10, 0x0d, 0xf2, 0xbd, 0x90, 0x25, 0xea, 0x3b, 0xcc, - 0x3b, 0x19, 0x32, 0x0d, 0x36, 0x64, 0x90, 0x0e, 0x4d, 0xe4, 0x90, 0x0f, - 0x12, 0xff, 0x35, 0xc1, 0x11, 0xc9, 0x9a, 0x3b, 0x53, 0x9a, 0x2a, 0x59, - 0x93, 0x94, 0xd4, 0x6b, 0x3c, 0x50, 0x2a, 0xf0, 0x83, 0xbd, 0x3f, 0x5d, - 0xca, 0xc2, 0x97, 0x26, 0x49, 0xe9, 0xa8, 0xcc, 0xf2, 0x8d, 0x54, 0x5b, - 0x7e, 0x40, 0x04, 0xe7, 0xb9, 0xec, 0xf0, 0xaf, 0x18, 0xa2, 0x11, 0x99, - 0x57, 0x36, 0x44, 0x98, 0x02, 0x7a, 0x2e, 0x81, 0x29, 0xbc, 0x7e, 0x84, - 0x81, 0x38, 0xbb, 0x0c, 0xa6, 0xb1, 0xec, 0x12, 0x0b, 0xcd, 0x38, 0x04, - 0xef, 0x6f, 0x0e, 0xe9, 0xeb, 0x10, 0x15, 0x0c, 0x1a, 0x90, 0x2a, 0x18, - 0xb0, 0x1d, 0xad, 0xa8, 0x68, 0xc1, 0x23, 0x0e, 0x3a, 0x24, 0x37, 0xb8, - 0x5c, 0x0c, 0x89, 0x3e, 0x64, 0x65, 0x98, 0xcd, 0x94, 0x68, 0x67, 0x73, - 0xb1, 0x0b, 0xc2, 0x6c, 0x76, 0x89, 0x9e, 0x9b, 0x5b, 0x3d, 0x10, 0x57, - 0x60, 0x39, 0xd4, 0x21, 0xbd, 0x0f, 0x31, 0x63, 0x73, 0x75, 0x7d, 0x9b, - 0x4c, 0x57, 0x26, 0x28, 0x1e, 0xd6, 0x56, 0xaa, 0xe2, 0xd9, 0x4c, 0xcf, - 0x6e, 0x1e, 0xb7, 0x0b, 0xb4, 0x15, 0xb3, 0xeb, 0xe4, 0x3a, 0xa4, 0x31, - 0xf1, 0xa7, 0x6a, 0x1e, 0xdc, 0x68, 0x9c, 0x3d, 0xd8, 0x1a, 0xb9, 0x09, - 0x50, 0xfc, 0xee, 0xb9, 0x9a, 0xa2, 0xee, 0x7d, 0x48, 0x76, 0x97, 0x37, - 0x32, 0xfb, 0x6f, 0x43, 0xcc, 0x14, 0x5b, 0x1a, 0x5e, 0x3a, 0x9b, 0x4b, - 0x4f, 0xb3, 0x6d, 0xb4, 0x59, 0x36, 0x9e, 0x45, 0x4c, 0x48, 0xd0, 0x61, - 0xc8, 0x7c, 0x1c, 0x32, 0x9d, 0x86, 0x04, 0x86, 0x64, 0xcd, 0x74, 0xc4, - 0x63, 0x3d, 0xd9, 0x8c, 0x07, 0x9b, 0xe5, 0x68, 0x86, 0x0b, 0x7d, 0xec, - 0x9e, 0x21, 0x68, 0x0b, 0x63, 0x2f, 0x36, 0x3a, 0xd0, 0xf4, 0x78, 0x42, - 0x73, 0x14, 0x96, 0x66, 0x54, 0xb3, 0x24, 0xd3, 0x76, 0x31, 0xe3, 0x27, - 0x0f, 0x07, 0xe3, 0x13, 0xd6, 0x53, 0x38, 0x98, 0x93, 0x33, 0x8d, 0xa6, - 0x6a, 0x45, 0x66, 0x5a, 0x5d, 0xab, 0x59, 0x5d, 0xc3, 0xc1, 0x6c, 0x5b, - 0xec, 0xbb, 0x70, 0xb0, 0xfb, 0x66, 0x5a, 0x81, 0xa6, 0x9c, 0x0d, 0x03, - 0x8c, 0xbf, 0xd5, 0xbe, 0x1b, 0xa0, 0x8f, 0x0c, 0x03, 0xac, 0x52, 0xbc, - 0x7a, 0xbf, 0x83, 0x56, 0x34, 0x0c, 0x6e, 0x17, 0xf3, 0xe5, 0xfd, 0x6b, - 0x35, 0xac, 0x13, 0x38, 0x76, 0xa1, 0xa9, 0x56, 0x3a, 0x32, 0xa1, 0x5b, - 0xed, 0x1b, 0x7f, 0x9e, 0xd0, 0x7e, 0x11, 0x1d, 0x5e, 0x11, 0x7c, 0x83, - 0x67, 0xf4, 0x1b, 0x3e, 0xfa, 0xee, 0xdb, 0x77, 0x6a, 0xd6, 0x60, 0x43, - 0x4b, 0xf5, 0x42, 0xb8, 0x47, 0x87, 0xa8, 0xb6, 0x7e, 0x57, 0xcd, 0xa8, - 0x58, 0xae, 0x0c, 0xa3, 0xc4, 0xef, 0x86, 0x72, 0x88, 0x4f, 0x7b, 0x3c, - 0xda, 0xbe, 0xf3, 0x88, 0x7d, 0xb5, 0x7e, 0xba, 0x42, 0xbb, 0x22, 0xf1, - 0x3b, 0x0f, 0x81, 0x57, 0x33, 0x26, 0x1c, 0x0d, 0x93, 0x91, 0x18, 0xec, - 0xbb, 0x1b, 0x46, 0xcb, 0xed, 0xef, 0x7c, 0xdc, 0xcc, 0xdb, 0x6c, 0xfe, - 0x5d, 0xe6, 0x77, 0x75, 0x0a, 0x13, 0xbf, 0x5b, 0x2e, 0x67, 0x3c, 0x1c, - 0x57, 0xb3, 0x71, 0xea, 0x86, 0xc1, 0x17, 0xaf, 0xb4, 0x9a, 0xf8, 0x9d, - 0x5b, 0x93, 0x27, 0x3a, 0x26, 0x62, 0xd0, 0xef, 0x32, 0x09, 0xea, 0xe9, - 0x27, 0xc5, 0xa0, 0xdf, 0x2d, 0xf6, 0xdd, 0x2b, 0xda, 0xc1, 0xef, 0x29, - 0xd5, 0x78, 0x99, 0x7f, 0x77, 0x78, 0xbf, 0xff, 0x4c, 0x17, 0x73, 0x1b, - 0xc8, 0x28, 0x3f, 0x15, 0x30, 0xca, 0x4c, 0xa1, 0xdc, 0x3a, 0xca, 0xed, - 0x98, 0xc0, 0x73, 0x73, 0x0f, 0x1d, 0x81, 0x07, 0x90, 0xed, 0xc0, 0xae, - 0x8e, 0xc6, 0x62, 0xdf, 0x05, 0xb0, 0xef, 0xd8, 0x21, 0xf7, 0x34, 0x37, - 0x48, 0x3e, 0xad, 0x26, 0x04, 0xf0, 0xb3, 0x56, 0xfb, 0x6e, 0xb0, 0x83, - 0x70, 0x35, 0x21, 0x80, 0x1f, 0x55, 0xec, 0xbb, 0xce, 0x0c, 0x98, 0xd5, - 0x84, 0x80, 0xa6, 0xd9, 0xd4, 0x00, 0xf1, 0x6a, 0x5a, 0x63, 0x30, 0x33, - 0x63, 0x64, 0xfa, 0x33, 0x9b, 0x18, 0x45, 0xcc, 0x71, 0xee, 0xa1, 0xcd, - 0xcc, 0x18, 0x50, 0x0c, 0x11, 0x0a, 0x6a, 0xed, 0xe9, 0xd5, 0xfc, 0x40, - 0x9d, 0xb3, 0x44, 0x2a, 0xea, 0xfe, 0xe4, 0x05, 0x27, 0xf1, 0x90, 0x2f, - 0xdc, 0x68, 0x4b, 0x76, 0xe4, 0x06, 0xe5, 0x97, 0x70, 0x46, 0x16, 0xd7, - 0xdb, 0x85, 0x0e, 0xf5, 0x73, 0x2a, 0xa7, 0x97, 0xc4, 0xf9, 0x86, 0x5e, - 0xd4, 0x2f, 0xee, 0x3d, 0xd3, 0x6e, 0x5e, 0x48, 0x70, 0xfc, 0x82, 0x43, - 0xc2, 0xcf, 0x45, 0x8b, 0x76, 0xed, 0xe9, 0xaa, 0x75, 0x4c, 0xb2, 0x34, - 0xd4, 0x5f, 0x63, 0xa2, 0x5f, 0x1c, 0x61, 0xf6, 0x4e, 0x03, 0x0e, 0xf6, - 0xdc, 0xd3, 0x69, 0xec, 0x70, 0x4a, 0xcd, 0x34, 0x67, 0x17, 0x53, 0xd6, - 0xe6, 0x6b, 0x16, 0xd3, 0x7a, 0x83, 0x6d, 0xc2, 0x66, 0xc4, 0x0e, 0x76, - 0xfa, 0xc2, 0xab, 0x2d, 0xd4, 0x7c, 0xc9, 0xb6, 0x73, 0xd2, 0x8e, 0x1d, - 0x8e, 0xc8, 0xb1, 0xc5, 0x06, 0x4f, 0x2d, 0xf6, 0x2f, 0x73, 0xb3, 0x16, - 0xda, 0xdc, 0xf8, 0x99, 0x8c, 0x48, 0x4f, 0x3e, 0x14, 0xfc, 0x4c, 0x49, - 0x6f, 0x99, 0x4e, 0x3b, 0x2c, 0xe8, 0xdb, 0x2f, 0xdc, 0x3d, 0x68, 0xbc, - 0xc8, 0x98, 0x42, 0x50, 0x27, 0x13, 0xfb, 0xe9, 0x67, 0x8c, 0x13, 0xd3, - 0xe3, 0x15, 0xdc, 0xce, 0x8d, 0xfe, 0xa7, 0x79, 0x03, 0x75, 0x13, 0x3b, - 0xba, 0x8f, 0xc7, 0xc8, 0x49, 0x71, 0x55, 0x48, 0xaf, 0xb3, 0xf8, 0x09, - 0x56, 0xaa, 0x72, 0x9c, 0x29, 0xae, 0x0b, 0x45, 0xd2, 0xf3, 0x8b, 0xae, - 0x1b, 0xb7, 0x86, 0xc3, 0x9a, 0xe6, 0xa0, 0x11, 0xdb, 0x0b, 0xd5, 0x38, - 0x71, 0x58, 0xe6, 0xb0, 0xcc, 0x61, 0x33, 0x87, 0x2d, 0x97, 0x0a, 0xc7, - 0xf5, 0x61, 0xa4, 0x9a, 0x09, 0x6c, 0xf4, 0xd4, 0x74, 0xee, 0xf1, 0x55, - 0xfd, 0x96, 0xe8, 0xd5, 0xb9, 0x12, 0x0c, 0x07, 0x6d, 0x38, 0x73, 0x98, - 0xdd, 0xa3, 0x65, 0xa3, 0xe1, 0xcd, 0x4c, 0x96, 0x31, 0xbe, 0xe1, 0x78, - 0x43, 0x3d, 0x10, 0x75, 0x4f, 0x8c, 0x1d, 0x31, 0x7e, 0x47, 0xf4, 0xed, - 0x11, 0x29, 0xf3, 0xe2, 0xe5, 0x29, 0x5a, 0x1c, 0xa7, 0x67, 0x87, 0x5d, - 0xca, 0xd7, 0xfa, 0xf2, 0x17, 0xbb, 0x2c, 0xe8, 0x73, 0x98, 0x2b, 0x26, - 0x88, 0xe9, 0xb5, 0x2e, 0x23, 0xdb, 0x75, 0x9f, 0xce, 0x25, 0xe9, 0xd8, - 0x27, 0x78, 0x98, 0xe6, 0xd0, 0xa7, 0x79, 0x58, 0x9f, 0xf5, 0xba, 0x4f, - 0xef, 0x27, 0xe8, 0xb1, 0x4f, 0xbc, 0xd5, 0xa7, 0x3d, 0xf7, 0x29, 0x37, - 0xfb, 0x2c, 0xd7, 0x7d, 0xee, 0x2d, 0xfa, 0x46, 0x9f, 0xee, 0x26, 0x61, - 0xc2, 0xd7, 0x25, 0x4c, 0x7f, 0x93, 0x30, 0x37, 0x17, 0x7d, 0xd5, 0xe7, - 0xf6, 0xa2, 0x6f, 0xf4, 0x19, 0x6e, 0x12, 0xe6, 0xe6, 0xa2, 0x1f, 0xc8, - 0x0d, 0x0f, 0x25, 0xcc, 0x97, 0x2c, 0xfa, 0x5e, 0x9f, 0x6f, 0xfe, 0x39, - 0x6e, 0xc1, 0x21, 0x72, 0x57, 0x4d, 0x64, 0x9d, 0xd4, 0x82, 0xc9, 0x1e, - 0xcd, 0xbd, 0xd5, 0x67, 0xbc, 0x36, 0xcc, 0xbc, 0x78, 0xc6, 0xa5, 0xe6, - 0x4a, 0xe8, 0x28, 0x5b, 0xab, 0xf7, 0x56, 0xf0, 0x56, 0xb2, 0xd6, 0xe2, - 0xf5, 0x09, 0x8b, 0x53, 0xc2, 0xeb, 0x93, 0xd4, 0xf4, 0xd2, 0xd3, 0xda, - 0x42, 0x49, 0xd9, 0x3c, 0xc9, 0x04, 0x0b, 0x6d, 0x6a, 0x99, 0xcc, 0x18, - 0x3b, 0x7a, 0xa8, 0x38, 0x41, 0x52, 0x41, 0xfd, 0x9b, 0xfa, 0x8e, 0x91, - 0x69, 0x18, 0x73, 0x28, 0x61, 0xa4, 0xad, 0xee, 0xe2, 0x98, 0x67, 0x93, - 0x7b, 0xba, 0xf4, 0x93, 0xbb, 0xa2, 0x63, 0x60, 0x30, 0x60, 0x8c, 0xee, - 0x91, 0x26, 0x78, 0x82, 0xa8, 0x54, 0x13, 0x54, 0x2d, 0xbd, 0x3a, 0x31, - 0x16, 0xcc, 0x3f, 0x9d, 0x07, 0x86, 0xb2, 0x73, 0xa0, 0xf3, 0x37, 0x45, - 0x1a, 0x0e, 0x63, 0x62, 0xb6, 0xc5, 0x1c, 0x62, 0x99, 0x71, 0xeb, 0xe8, - 0xba, 0x13, 0x3a, 0xb0, 0x1d, 0x2a, 0x56, 0x03, 0xd5, 0x2d, 0xfd, 0xeb, - 0xe6, 0x10, 0x04, 0x05, 0x3a, 0x66, 0xba, 0xb6, 0x8b, 0xfd, 0xea, 0x49, - 0x73, 0xec, 0xdc, 0xcc, 0x0d, 0x56, 0x84, 0xb6, 0x87, 0x13, 0xb7, 0x1a, - 0x91, 0xf1, 0x52, 0x68, 0x9a, 0x94, 0xea, 0x52, 0xad, 0xce, 0x39, 0x8f, - 0x9c, 0x5d, 0xd3, 0xd2, 0x52, 0xf8, 0x72, 0x74, 0x9f, 0x9c, 0xdd, 0xef, - 0x59, 0xec, 0xef, 0x9f, 0xdd, 0x17, 0xef, 0xec, 0x3d, 0x46, 0x09, 0x8e, - 0x2e, 0x3a, 0xba, 0x13, 0xdf, 0xb5, 0xce, 0x77, 0x82, 0xa4, 0xfb, 0x24, - 0x1b, 0x0f, 0xee, 0x93, 0x04, 0xf7, 0xe8, 0x4f, 0x52, 0xd1, 0x99, 0x9b, - 0x54, 0xa0, 0x21, 0x19, 0x32, 0x3a, 0x08, 0x59, 0x8b, 0x0c, 0x25, 0x02, - 0xbe, 0x1d, 0xe3, 0x60, 0x16, 0x26, 0x92, 0xd6, 0x4f, 0x05, 0x56, 0x3a, - 0x88, 0xcb, 0x96, 0x0b, 0xfe, 0xe6, 0xad, 0xc5, 0x5b, 0xb3, 0xdb, 0x09, - 0x93, 0xb7, 0x7c, 0x83, 0x56, 0x6f, 0xcd, 0x17, 0x9b, 0x16, 0xd8, 0xed, - 0xa0, 0xa0, 0xdc, 0x45, 0xad, 0xb6, 0xee, 0x21, 0x63, 0x71, 0x60, 0xc2, - 0x8e, 0x8d, 0x1e, 0x7b, 0x9b, 0xaa, 0x65, 0x4c, 0xe4, 0x53, 0xe3, 0xa9, - 0x94, 0x0e, 0x57, 0xe2, 0x8f, 0x98, 0x04, 0x26, 0xd3, 0xe2, 0xda, 0x83, - 0x8f, 0x02, 0xae, 0x11, 0x53, 0xc4, 0x8a, 0xc8, 0xa2, 0x1d, 0xae, 0x03, - 0xd6, 0x17, 0xf0, 0xeb, 0x28, 0xc6, 0x30, 0xb3, 0x6e, 0x48, 0xd1, 0xc7, - 0xc9, 0x19, 0x9c, 0xce, 0x48, 0x95, 0x21, 0xf8, 0x6d, 0xbf, 0x5e, 0x6b, - 0xce, 0x91, 0xfd, 0xba, 0xdf, 0xa0, 0x43, 0x24, 0xe4, 0x6c, 0xbf, 0xbb, - 0x18, 0x95, 0x1d, 0xc4, 0x2f, 0xca, 0xbd, 0x39, 0x4a, 0x13, 0x3c, 0x27, - 0x75, 0x73, 0x5a, 0xe5, 0x25, 0x7d, 0xe5, 0x43, 0x63, 0x3b, 0xb7, 0xb6, - 0xe6, 0x07, 0x2f, 0x5d, 0x25, 0xe0, 0x04, 0x92, 0x8e, 0x20, 0x32, 0xb8, - 0x9c, 0xe1, 0x04, 0x06, 0x50, 0xe8, 0x12, 0xf0, 0xd8, 0xf8, 0xf3, 0x86, - 0xf7, 0x20, 0xe8, 0x00, 0xfe, 0x0a, 0x60, 0x1b, 0xdb, 0x87, 0x0c, 0x39, - 0x9f, 0xb0, 0x1f, 0x63, 0x8b, 0x7d, 0xe1, 0x7e, 0xfc, 0xce, 0xe1, 0x7f, - 0xee, 0xda, 0xff, 0xf2, 0xc3, 0x8d, 0x58, 0x76, 0xd9, 0x68, 0x0f, 0x00, - 0xfc, 0xa1, 0x7c, 0xa3, 0x8f, 0x9b, 0x2c, 0x88, 0x89, 0xbc, 0xba, 0x13, - 0x13, 0x69, 0x0b, 0xa2, 0x57, 0x37, 0x62, 0x22, 0xea, 0xcf, 0x23, 0xd0, - 0x7c, 0x15, 0x13, 0x29, 0x1d, 0x75, 0xef, 0x78, 0x15, 0x13, 0x99, 0xe2, - 0x21, 0xb0, 0xa0, 0x91, 0x22, 0x8f, 0x89, 0xcc, 0x46, 0xbf, 0xa2, 0xe2, - 0xbb, 0x58, 0x28, 0x04, 0x11, 0x0a, 0xfc, 0xc8, 0x67, 0x2c, 0x28, 0xec, - 0x0f, 0x66, 0xe2, 0xa8, 0x6a, 0xf5, 0x98, 0xc8, 0xd8, 0xc2, 0x68, 0x9a, - 0x20, 0xd7, 0x88, 0x89, 0x78, 0x44, 0xb8, 0x7e, 0xef, 0x31, 0x11, 0xb9, - 0x47, 0x6b, 0xfc, 0xed, 0xc1, 0x97, 0x95, 0x37, 0x32, 0x35, 0x5d, 0x43, - 0xc4, 0x3d, 0xa7, 0xde, 0x63, 0xea, 0xa6, 0x5f, 0x30, 0xe3, 0xcc, 0x28, - 0x76, 0xb6, 0x61, 0x4e, 0x83, 0x84, 0x13, 0x6e, 0x92, 0x60, 0xb5, 0x0e, - 0x63, 0xd4, 0x6b, 0x09, 0x0c, 0x8c, 0x5b, 0x58, 0x38, 0xf0, 0x37, 0x6a, - 0x07, 0x2d, 0x03, 0x1f, 0x99, 0x77, 0x1f, 0x19, 0x62, 0x9f, 0x1a, 0x14, - 0x8a, 0x64, 0xdb, 0x03, 0x1e, 0xe7, 0x96, 0x45, 0x92, 0x61, 0x7a, 0x0f, - 0x93, 0x62, 0x44, 0xc1, 0x70, 0x2c, 0x70, 0xc3, 0x4d, 0x82, 0xc1, 0x96, - 0x6e, 0xca, 0x1f, 0x82, 0xca, 0x13, 0x87, 0x4d, 0x1c, 0x96, 0x39, 0xcc, - 0x63, 0xca, 0x0b, 0x87, 0x2d, 0xe0, 0x77, 0xbb, 0x47, 0xc7, 0x7b, 0x34, - 0xde, 0x48, 0xe5, 0xc0, 0xfc, 0x23, 0x87, 0x8d, 0x1c, 0x36, 0x71, 0x58, - 0xe6, 0xb0, 0xcc, 0x61, 0x1e, 0xd2, 0xf1, 0xdc, 0x13, 0x4d, 0xcf, 0x72, - 0x38, 0x23, 0x33, 0x0f, 0xc1, 0xb9, 0x71, 0x9d, 0xe5, 0x4a, 0xac, 0xaa, - 0xa5, 0x07, 0x21, 0xfa, 0x03, 0xe3, 0x05, 0x8f, 0x9c, 0xd1, 0x23, 0x97, - 0xf6, 0xd7, 0x0d, 0x85, 0x38, 0xa2, 0xff, 0x0f, 0x02, 0xc7, 0x66, 0x05, - 0x3b, 0xdc, 0x00, 0x00 -}; - -const GFXglyph Oswald_Medium80pt7bGlyphs[] PROGMEM = { - { 0, 1, 1, 38, 0, 0 }, // 0x20 ' ' - { 1, 21, 127, 37, 8, -126 }, // 0x21 '!' - { 335, 43, 43, 49, 4, -126 }, // 0x22 '"' - { 567, 68, 127, 80, 6, -126 }, // 0x23 '#' - { 1647, 67, 156, 76, 5, 116 }, // 0x24 '$' - { 2954, 136, 127, 149, 6, -126 }, // 0x25 '%' - { 5113, 76, 130, 92, 8, -127 }, // 0x26 '&' - { 6348, 18, 43, 23, 4, -126 }, // 0x27 ''' - { 6445, 35, 157, 50, 10, -127 }, // 0x28 '(' - { 7132, 34, 157, 46, 5, -127 }, // 0x29 ')' - { 7800, 54, 55, 64, 7, -126 }, // 0x2A '*' - { 8172, 60, 64, 68, 4, -96 }, // 0x2B '+' - { 8652, 20, 42, 33, 7, -20 }, // 0x2C ',' - { 8757, 38, 14, 49, 6, -52 }, // 0x2D '-' - { 8824, 21, 21, 34, 7, -20 }, // 0x2E '.' - { 8880, 50, 127, 62, 6, -126 }, // 0x2F '/' - { 9674, 66, 130, 84, 9, -127 }, // 0x30 '0' - { 10747, 41, 127, 60, 4, -126 }, // 0x31 '1' - { 11398, 67, 128, 78, 6, -127 }, // 0x32 '2' - { 12470, 66, 130, 78, 6, -127 }, // 0x33 '3' - { 13543, 71, 127, 79, 5, -126 }, // 0x34 '4' - { 14671, 65, 129, 77, 7, -126 }, // 0x35 '5' - { 15720, 66, 130, 82, 9, -127 }, // 0x36 '6' - { 16793, 56, 127, 65, 3, -126 }, // 0x37 '7' - { 17682, 66, 130, 80, 7, -127 }, // 0x38 '8' - { 18755, 67, 130, 82, 6, -127 }, // 0x39 '9' - { 19844, 20, 74, 37, 10, -85 }, // 0x3A ':' - { 20029, 21, 102, 39, 10, -88 }, // 0x3B ';' - { 20297, 47, 67, 60, 6, -98 }, // 0x3C '<' - { 20691, 49, 42, 67, 9, -85 }, // 0x3D '=' - { 20949, 47, 67, 60, 9, -98 }, // 0x3E '>' - { 21343, 64, 128, 76, 6, -127 }, // 0x3F '?' - { 22367, 132, 147, 145, 8, -126 }, // 0x40 '@' - { 24793, 76, 127, 82, 3, -126 }, // 0x41 'A' - { 26000, 72, 127, 87, 10, -126 }, // 0x42 'B' - { 27143, 70, 130, 85, 8, -127 }, // 0x43 'C' - { 28281, 70, 127, 87, 10, -126 }, // 0x44 'D' - { 29393, 53, 127, 67, 10, -126 }, // 0x45 'E' - { 30235, 52, 127, 65, 10, -126 }, // 0x46 'F' - { 31061, 71, 130, 88, 8, -127 }, // 0x47 'G' - { 32215, 72, 127, 92, 10, -126 }, // 0x48 'H' - { 33358, 23, 127, 43, 10, -126 }, // 0x49 'I' - { 33724, 39, 130, 51, 2, -126 }, // 0x4A 'J' - { 34358, 72, 127, 83, 10, -126 }, // 0x4B 'K' - { 35501, 53, 127, 66, 10, -126 }, // 0x4C 'L' - { 36343, 89, 127, 107, 9, -126 }, // 0x4D 'M' - { 37756, 66, 127, 85, 10, -126 }, // 0x4E 'N' - { 38804, 73, 130, 88, 8, -127 }, // 0x4F 'O' - { 39991, 69, 127, 83, 10, -126 }, // 0x50 'P' - { 41087, 73, 153, 88, 8, -127 }, // 0x51 'Q' - { 42484, 72, 127, 88, 10, -126 }, // 0x52 'R' - { 43627, 67, 130, 77, 6, -127 }, // 0x53 'S' - { 44716, 63, 127, 67, 2, -126 }, // 0x54 'T' - { 45717, 71, 129, 89, 9, -126 }, // 0x55 'U' - { 46862, 74, 127, 81, 3, -126 }, // 0x56 'V' - { 48037, 102, 127, 112, 5, -126 }, // 0x57 'W' - { 49657, 75, 127, 78, 2, -126 }, // 0x58 'X' - { 50848, 73, 127, 76, 2, -126 }, // 0x59 'Y' - { 52007, 58, 127, 67, 5, -126 }, // 0x5A 'Z' - // Euro sign ([) - ASCII code 91 - { 52928, 79, 130, 83, 0, -127 }, // 0x5B '[' - // Backslash placeholder - ASCII code 92 - { 0, 0, 0, 0, 0, 0 }, // 0x5C '\' - // Pound sign (]) - ASCII code 93 - { 54212, 63, 128, 70, 2, -127 }, // 0x5D ']' - // Yen sign (^) - ASCII code 94 - { 55220, 73, 127, 73, 1, -126 } // 0x5E '^' - }; - - -// const GFXfont Oswald_Medium80pt7b PROGMEM = { -// (uint8_t *)Oswald_Medium80pt7bBitmaps, -// (GFXglyph *)Oswald_Medium80pt7bGlyphs, -// 0x20, 0x5A, 232 }; - -// Approx. 53348 bytes -// Font properties -static constexpr FontData Oswald_Medium80pt7b_Properties = { - Oswald_Medium80pt7bBitmaps_Gzip, - Oswald_Medium80pt7bGlyphs, - sizeof(Oswald_Medium80pt7bBitmaps_Gzip), - 56626, // Original size - 0x20, // First char - 0x5E, // Last char - 232 // yAdvance -}; diff --git a/src/fonts/sats-symbol.h b/src/fonts/sats-symbol.h index 182c6ea..d21a9a5 100644 --- a/src/fonts/sats-symbol.h +++ b/src/fonts/sats-symbol.h @@ -1,235 +1,201 @@ -#pragma once - -#include -#include -#include "fonts.hpp" - -const uint8_t Satoshi_Symbol90pt7bBitmaps_Gzip[] = { - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x63, 0x60, - 0x60, 0x60, 0xe0, 0xff, 0xc7, 0x00, 0x05, 0xcc, 0xff, 0x1b, 0x60, 0xcc, - 0xff, 0x0f, 0x60, 0x2c, 0xfb, 0x1f, 0x30, 0xd6, 0x60, 0x53, 0x38, 0x28, - 0x81, 0xfd, 0x7f, 0x3a, 0x83, 0x81, 0xf6, 0x30, 0x1a, 0xe0, 0xa7, 0xb7, - 0xff, 0x0f, 0x0c, 0xb4, 0x8f, 0x51, 0x01, 0x33, 0xbd, 0xfd, 0xff, 0x61, - 0xa0, 0x7d, 0x8c, 0x17, 0x0c, 0x8e, 0x92, 0x82, 0x44, 0x85, 0x54, 0x8f, - 0x23, 0x88, 0xe1, 0xec, 0xff, 0xa1, 0x56, 0xf2, 0xff, 0xff, 0x03, 0x61, - 0xc8, 0xff, 0x87, 0x3a, 0xc7, 0x1e, 0x16, 0x8d, 0xf5, 0x30, 0xa7, 0xc2, - 0x12, 0x36, 0xe3, 0x7f, 0xa8, 0xeb, 0x98, 0x47, 0x8d, 0x19, 0x35, 0x66, - 0x78, 0x1b, 0x43, 0x65, 0xf0, 0x00, 0x00, 0xc7, 0x63, 0x9f, 0x4b, 0xde, - 0x08, 0x00, 0x00 -}; -// unsigned int satoshi_bin_gz_len = 123; - - -// const uint8_t Satoshi_Symbol90pt7bBitmaps[] PROGMEM = { -// 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -// 0x00, 0x00, 0x03, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -// 0x00, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, -// 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFE, 0x00, -// 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xFF, 0x80, 0x00, 0x00, -// 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x00, -// 0x00, 0x00, 0x00, 0x00, 0x3F, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -// 0x00, 0x00, 0x0F, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -// 0x03, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, -// 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xF8, 0x00, -// 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFE, 0x00, 0x00, 0x00, -// 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, -// 0x00, 0x00, 0x00, 0x00, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -// 0x00, 0x00, 0x3F, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -// 0x0F, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xFF, -// 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -// 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -// 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -// 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -// 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -// 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -// 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -// 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -// 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -// 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -// 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -// 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -// 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -// 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, -// 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, -// 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, -// 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, -// 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, -// 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, -// 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, -// 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, -// 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, -// 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, -// 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -// 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -// 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -// 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -// 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -// 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -// 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -// 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -// 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -// 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -// 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -// 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, -// 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, -// 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, -// 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, -// 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, -// 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, -// 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, -// 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, -// 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, -// 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, -// 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -// 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -// 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -// 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -// 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -// 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -// 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -// 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -// 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -// 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -// 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -// 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xFF, -// 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, -// 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, -// 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, -// 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, -// 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, -// 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, -// 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, -// 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, -// 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, -// 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -// 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -// 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -// 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -// 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -// 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -// 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -// 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -// 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -// 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -// 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -// 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -// 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -// 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, -// 0x00, 0x00, 0x00, 0x00, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -// 0x00, 0x00, 0x3F, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -// 0x0F, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xFF, -// 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xE0, 0x00, -// 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xF8, 0x00, 0x00, 0x00, -// 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, -// 0x00, 0x00, 0x00, 0x03, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -// 0x00, 0x00, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -// 0x3F, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFE, -// 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xFF, 0x80, 0x00, -// 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xE0, 0x00, 0x00, 0x00, -// 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, -// 0x00, 0x00, 0x00, 0x0F, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -// 0x00, 0x03, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -// 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, -// 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, -// 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, -// 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, -// 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, -// 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, -// 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, -// 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xFF, 0xFE, -// 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFC, 0x00, 0x00, 0x00, -// 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -// 0x3F, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xE0, -// 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x00, -// 0x00, 0x00, 0x01, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, -// 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xFF, 0xFE, 0x00, -// 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x00, -// 0x00, 0x00, 0x1F, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, -// 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xE0, 0x00, -// 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00, -// 0x00, 0x01, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xFF, -// 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xFF, 0xFE, 0x00, 0x00, -// 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, -// 0x00, 0x1F, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, -// 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xE0, 0x00, 0x00, -// 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, -// 0x01, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xFF, 0xFF, -// 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xFF, 0xFE, 0x00, 0x00, 0x00, -// 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -// 0x1F, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xF0, -// 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xE0, 0x00, 0x00, 0x00, -// 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, -// 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0x00, -// 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x00, -// 0x00, 0x00, 0x0F, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, -// 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xF0, 0x00, -// 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x00, -// 0x00, 0x00, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xFF, -// 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0x00, 0x00, -// 0x00, 0x00, 0x00, 0x00, 0x07, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, -// 0x00, 0x0F, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0xFF, -// 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xF0, 0x00, 0x00, -// 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, -// 0x00, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFF, -// 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0x00, 0x00, 0x00, -// 0x00, 0x00, 0x00, 0x07, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -// 0x0F, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xF8, -// 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xF0, 0x00, 0x00, 0x00, -// 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -// 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0x80, -// 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, -// 0x00, 0x00, 0x07, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, -// 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xF8, 0x00, -// 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, -// 0x00, 0x00, 0x7F, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, -// 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0x80, 0x00, -// 0x00, 0x00, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, -// 0x00, 0x07, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFF, -// 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xF8, 0x00, 0x00, -// 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, -// 0x00, 0x7F, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, -// 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0x80, 0x00, 0x00, -// 0x00, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -// 0x07, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFC, -// 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xF8, 0x00, 0x00, 0x00, -// 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -// 0x7F, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xC0, -// 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00, -// 0x00, 0x00, 0x03, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, -// 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFC, 0x00, -// 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x00, -// 0x00, 0x00, 0x3F, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, -// 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xC0, 0x00, -// 0x00, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, -// 0x00, 0x03, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xFF, -// 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFC, 0x00, 0x00, -// 0x00, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, -// 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, -// 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, -// 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, -// 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, -// 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, -// 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, -// 0xFF, 0xE0 }; +const uint8_t Satoshi_Symbol90pt7bBitmaps[] PROGMEM = { + 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x03, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, + 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFE, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xFF, 0x80, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x3F, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0F, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x03, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, + 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xF8, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFE, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x3F, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x0F, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xFF, + 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x3F, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x0F, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xFF, + 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xE0, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xF8, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x03, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x3F, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFE, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xFF, 0x80, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xE0, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x0F, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x03, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xFF, 0xFE, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFC, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x3F, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xE0, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x01, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, + 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xFF, 0xFE, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x1F, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, + 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xE0, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x01, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xFF, + 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xFF, 0xFE, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x1F, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, + 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xE0, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xFF, 0xFF, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xFF, 0xFE, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x1F, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xF0, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xE0, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0F, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, + 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xF0, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xFF, + 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x07, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x0F, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0xFF, + 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xF0, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFF, + 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x07, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x0F, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xF8, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xF0, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0x80, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x07, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, + 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xF8, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x7F, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, + 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0x80, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x07, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFF, + 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xF8, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x7F, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, + 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0x80, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x07, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFC, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xF8, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x7F, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xC0, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x03, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, + 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFC, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x3F, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, + 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xC0, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x03, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xFF, + 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFC, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xE0 }; const GFXglyph Satoshi_Symbol90pt7bGlyphs[] PROGMEM = { { 0, 82, 127, 99, 8, -126 }, { 1302, 71, 109, 93, 0, -117 } }; // 0x53 'S' -// const GFXfont Satoshi_Symbol90pt7b PROGMEM = { -// (uint8_t *)Satoshi_Symbol90pt7bBitmaps, -// (GFXglyph *)Satoshi_Symbol90pt7bGlyphs, -// 0x53, 0x53, 192 }; - - // Font properties -static constexpr FontData Satoshi_Symbol90pt7b_Properties = { - Satoshi_Symbol90pt7bBitmaps_Gzip, - Satoshi_Symbol90pt7bGlyphs, - sizeof(Satoshi_Symbol90pt7bBitmaps_Gzip), - 2270, // Original size - 0x53, // First char - 0x53, // Last char - 192 // yAdvance -}; - +const GFXfont Satoshi_Symbol90pt7b PROGMEM = { + (uint8_t *)Satoshi_Symbol90pt7bBitmaps, + (GFXglyph *)Satoshi_Symbol90pt7bGlyphs, + 0x53, 0x53, 192 }; // Approx. 2284 bytes diff --git a/src/icons/icons.cpp b/src/icons/icons.cpp deleted file mode 100644 index d9ae65c..0000000 --- a/src/icons/icons.cpp +++ /dev/null @@ -1,542 +0,0 @@ -#include "icons.h" - -// 'lightning-bolt', 122x122px -const unsigned char epd_icons_lightning_bolt [] PROGMEM = { - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xbf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x07, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x07, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x07, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x07, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0 -}; -// 'rocket-launch', 122x122px -const unsigned char epd_icons_rocket_launch [] PROGMEM = { - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x01, 0xf8, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x07, 0xfe, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x0f, 0xff, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x1f, 0xff, 0x80, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x1f, 0xff, 0x80, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x3f, 0xff, 0xc0, 0x00, 0x7f, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x3f, 0xff, 0xc0, 0x00, 0x7f, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x3f, 0xff, 0xc0, 0x00, 0x7f, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x3f, 0xff, 0xc0, 0x00, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xfe, 0xf8, 0x00, 0x00, 0x3f, 0xff, 0xc0, 0x00, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xf1, 0xf0, 0x00, 0x00, 0x3f, 0xff, 0xc0, 0x01, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xc1, 0xf0, 0x00, 0x00, 0x3f, 0xff, 0xc0, 0x01, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0x03, 0xe0, 0x00, 0x00, 0x1f, 0xff, 0x80, 0x01, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xfc, 0x03, 0xc0, 0x00, 0x00, 0x0f, 0xff, 0x00, 0x03, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xf0, 0x07, 0xc0, 0x00, 0x00, 0x07, 0xfe, 0x00, 0x03, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0x80, 0x0f, 0x80, 0x00, 0x00, 0x03, 0xfc, 0x00, 0x07, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xfe, 0x00, 0x0f, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xf8, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xe0, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0x80, 0x00, 0x3e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0x80, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xe0, 0x00, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xf8, 0x00, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0x00, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xc0, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xf0, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xfc, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xf8, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xf0, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xe0, 0x7e, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xc0, 0xff, 0x00, 0x00, 0x00, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0x81, 0xff, 0x80, 0x00, 0x00, 0x07, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0x03, 0xff, 0xc0, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xfe, 0x07, 0xe7, 0xe0, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xfc, 0x0f, 0xc3, 0xf0, 0x00, 0x00, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xf8, 0x1f, 0x81, 0xf8, 0x00, 0x03, 0xfe, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xf0, 0x3f, 0x00, 0xfc, 0x00, 0x0f, 0xf8, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xe0, 0x7e, 0x00, 0x7e, 0x00, 0x3f, 0xe0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xc0, 0xfc, 0x00, 0x3f, 0x80, 0xff, 0x81, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0x81, 0xf8, 0x00, 0x7f, 0xff, 0xfe, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0x03, 0xf0, 0x00, 0xff, 0xff, 0xf8, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0x07, 0xe0, 0x01, 0xf3, 0xff, 0xe0, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0x0f, 0xc0, 0x03, 0xe0, 0xff, 0x80, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0x1f, 0x80, 0x07, 0xc0, 0xff, 0x00, 0x07, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0x3f, 0x00, 0x0f, 0x81, 0xff, 0x00, 0x07, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0x7e, 0x00, 0x1f, 0x03, 0xff, 0x80, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xfc, 0x00, 0x3e, 0x07, 0xff, 0x80, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xf8, 0x00, 0x7c, 0x0f, 0xff, 0x80, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xf0, 0x00, 0xf8, 0x1f, 0xff, 0xc0, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xe0, 0x01, 0xf0, 0x3f, 0xff, 0xc0, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xc0, 0x03, 0xe0, 0x7f, 0xff, 0xe0, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0x80, 0x07, 0xc0, 0xff, 0xff, 0xe0, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0x00, 0x0f, 0x81, 0xff, 0xff, 0xf0, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0x00, 0x1f, 0x03, 0xff, 0xff, 0xf0, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0x00, 0x3e, 0x07, 0xff, 0xff, 0xf0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0x00, 0x7c, 0x0f, 0xff, 0xff, 0xf8, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0x00, 0xf8, 0x1f, 0xff, 0xff, 0xf9, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0x01, 0xf0, 0x3f, 0xff, 0xff, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0 -}; -// 'pickaxe', 122x122px -const unsigned char epd_icons_pickaxe [] PROGMEM = { - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xe7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xc1, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x07, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xfb, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x31, 0xef, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0xc7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xe0, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x7f, 0xf8, 0x00, 0x07, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x3f, 0xfd, 0x80, 0x03, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x1f, 0xff, 0xc0, 0x03, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x0f, 0xff, 0xe0, 0x01, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x07, 0xff, 0xf0, 0x00, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x07, 0xff, 0xf8, 0x00, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x0f, 0xff, 0xf8, 0x00, 0x7f, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x1f, 0xff, 0xfc, 0x00, 0x7f, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x3f, 0xff, 0xfe, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x7f, 0xff, 0xfe, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0xff, 0xff, 0xff, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x01, 0xff, 0xff, 0xff, 0x80, 0x1f, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x03, 0xff, 0xff, 0xff, 0x80, 0x0f, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x07, 0xff, 0xff, 0xff, 0xc0, 0x0f, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xe0, 0x0f, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xe0, 0x07, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xf0, 0x07, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x7f, 0xff, 0xff, 0xff, 0xf8, 0x0f, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x3f, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xff, 0xe0, 0x01, 0xff, 0xff, 0xff, 0xff, 0xfc, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xff, 0xc0, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xff, 0x80, 0x07, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xff, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xfe, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xfc, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xf8, 0x00, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xf0, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xe0, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xc0, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0x80, 0x07, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xfe, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xfc, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xf8, 0x00, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xf0, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xe0, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xc0, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0x80, 0x07, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xfe, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xfc, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xf8, 0x00, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xf0, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xe0, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xc0, 0x07, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0x80, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0x80, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xc0, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xe0, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xf0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xf9, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0 -}; - -const unsigned char epd_icons_bitaxe_logo [] PROGMEM = { - // 'bitaxe_dark copy', 88x220px - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xfc, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x7f, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x3e, 0xff, 0xff, 0xfd, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0xff, 0xff, 0xfc, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xfe, - 0x00, 0xff, 0xff, 0xfe, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x7f, 0xff, 0xff, 0x00, - 0x07, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x3f, 0xff, 0xff, 0xc0, 0x07, 0xff, 0xff, 0xff, 0xff, - 0xf8, 0x00, 0x3f, 0xff, 0xff, 0xe0, 0x07, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x1f, 0xff, 0xff, - 0xf0, 0x03, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x0f, 0xff, 0xff, 0xf8, 0x03, 0xff, 0xff, 0xff, - 0xff, 0xf0, 0x00, 0x07, 0xff, 0xff, 0xf8, 0x01, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x03, 0xff, - 0xff, 0xfc, 0x00, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0xff, 0xff, 0xfc, 0x00, 0x7f, 0xff, - 0xff, 0xff, 0xe0, 0x07, 0xf8, 0x7f, 0xff, 0xfd, 0xfc, 0x3f, 0xff, 0xff, 0xff, 0xe0, 0x07, 0xfe, - 0x3f, 0xff, 0xff, 0xfc, 0x1f, 0xff, 0xff, 0xff, 0xc0, 0x0f, 0xff, 0x1f, 0xff, 0xff, 0xf8, 0x07, - 0xff, 0xff, 0xff, 0xc0, 0x0f, 0xff, 0xcf, 0xff, 0xff, 0xf8, 0x01, 0xff, 0xff, 0xff, 0x80, 0x0f, - 0xff, 0xe7, 0xff, 0xff, 0xf8, 0x01, 0xff, 0xff, 0xff, 0x80, 0x1f, 0xff, 0xf3, 0xff, 0xff, 0xf0, - 0x01, 0xff, 0xff, 0xff, 0xc0, 0x1f, 0xff, 0xf3, 0xff, 0xff, 0xf0, 0x03, 0xff, 0xff, 0xff, 0xf0, - 0x1f, 0xff, 0xf9, 0xff, 0xff, 0xf0, 0x03, 0xff, 0xff, 0xff, 0xf8, 0x3f, 0xff, 0xfd, 0xff, 0xff, - 0xe0, 0x07, 0xff, 0xff, 0xff, 0xfe, 0x3f, 0xff, 0xfd, 0xff, 0xff, 0xe0, 0x07, 0xff, 0xff, 0xff, - 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xff, - 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xff, - 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, - 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xfc, 0xff, 0xff, 0xfe, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfd, 0xff, 0xff, 0xfe, - 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3f, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xfd, 0xff, 0xff, 0xfe, 0x7f, - 0xff, 0xfc, 0xff, 0xff, 0xff, 0xff, 0xfc, 0xff, 0xff, 0xff, 0x3f, 0xff, 0xfc, 0x7f, 0xff, 0xff, - 0xff, 0xfc, 0x00, 0x00, 0x7f, 0x3f, 0xff, 0xf8, 0x3f, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x7e, - 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x0f, 0xff, - 0xff, 0xff, 0xf0, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x00, 0x07, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, - 0x3c, 0x00, 0x00, 0x00, 0x01, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x03, - 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x07, 0xff, 0xff, 0xff, 0x80, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x0f, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xf8, - 0x1f, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xfc, 0x1f, 0xff, 0xf0, 0x03, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3f, 0xff, 0xe0, 0x07, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xe0, 0x07, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x07, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xc0, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, - 0x0f, 0xff, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xfd, 0xff, 0xff, 0x80, 0x1f, 0xff, 0xfc, 0xff, 0xff, - 0xff, 0xff, 0xfc, 0xff, 0xff, 0x00, 0x1f, 0xff, 0xfc, 0x7f, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, - 0x00, 0x3f, 0xff, 0xf8, 0x3f, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, - 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xf0, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, - 0x01, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x03, 0xff, 0xff, 0xff, 0xc0, - 0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x07, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0xf8, 0x00, - 0x00, 0x0f, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x01, 0xf8, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, - 0xe0, 0x0f, 0xff, 0xf1, 0xf8, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xf8, 0x1f, 0xff, 0xf9, 0xfc, - 0x00, 0x00, 0x7f, 0xff, 0xff, 0xff, 0xfc, 0x1f, 0xff, 0xf9, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0x3f, 0xff, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0xff, - 0xff, 0xff, 0xff, 0xfe, 0x7f, 0xff, 0xfd, 0xff, 0xff, 0xfc, 0x7f, 0xff, 0xff, 0xff, 0xfe, 0x3f, - 0xff, 0xf8, 0xff, 0xff, 0xf8, 0x3f, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x1f, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xfc, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x01, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xff, 0xff, 0xff, - 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, - 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xff, 0xe0, 0x07, 0xff, 0xf7, 0xff, 0xff, 0xfc, 0x3f, 0xff, - 0xff, 0xff, 0xe0, 0x07, 0xff, 0xf3, 0xff, 0xff, 0xfc, 0x1f, 0xff, 0xff, 0xff, 0xc0, 0x0f, 0xff, - 0xf3, 0xff, 0xff, 0xf8, 0x07, 0xff, 0xff, 0xff, 0xc0, 0x0f, 0xff, 0xf3, 0xff, 0xff, 0xf8, 0x01, - 0xff, 0xff, 0xff, 0x80, 0x0f, 0xff, 0xf9, 0xff, 0xff, 0xf0, 0x01, 0xff, 0xff, 0xff, 0x80, 0x1f, - 0xff, 0xf9, 0xff, 0xff, 0xf0, 0x03, 0xff, 0xff, 0xff, 0xc0, 0x1f, 0xff, 0xfc, 0xff, 0xff, 0xf0, - 0x03, 0xff, 0xff, 0xff, 0xf0, 0x1f, 0xff, 0xfe, 0x3f, 0xff, 0xe0, 0x03, 0xff, 0xff, 0xff, 0xf8, - 0x3f, 0xff, 0x7e, 0x1f, 0xff, 0xe0, 0x07, 0xff, 0xff, 0xff, 0xfe, 0x3f, 0xfc, 0xff, 0x03, 0xff, - 0xc0, 0x07, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0x80, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xff, - 0xff, 0x80, 0x01, 0xff, 0xc0, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xff, 0x80, 0x03, 0xff, 0xe0, - 0x00, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x0f, 0xff, 0xe0, 0x00, 0x00, 0x1f, 0xff, 0xff, - 0xff, 0xff, 0xe0, 0x1f, 0xff, 0xf0, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x3f, 0xff, - 0xf8, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x7f, 0xff, 0xf8, 0x00, 0x00, 0x3f, 0xff, - 0xff, 0xff, 0xff, 0xf0, 0x7f, 0xff, 0xf8, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xf0, 0xff, - 0xff, 0xfc, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xf0, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x7f, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0xff, 0xfe, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xfe, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xbf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0x8f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfd, 0xff, 0xff, 0xff, 0xff, 0x87, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xfc, 0xff, 0xff, 0xff, 0xff, 0x83, 0xff, 0xff, 0xfd, 0xff, 0xff, 0xfc, 0x7f, 0xff, 0xff, - 0xff, 0x83, 0xff, 0xff, 0xf8, 0xff, 0xff, 0xfc, 0x3f, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, - 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, - 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xff, 0xff, 0xff, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x0f, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0x80, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0x83, 0xff, 0xff, 0xf8, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0x83, 0xff, 0xff, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xc3, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf3, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xfd, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xfc, 0xff, 0xff, 0xff, 0xff, 0xfc, 0xff, 0xff, 0xf9, 0xff, 0xff, 0xf8, 0x7f, - 0xff, 0xf9, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xf0, 0xff, 0xf8, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xe0, 0x7f, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x07, 0xff, 0xc0, 0x3f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0x80, 0x1f, 0xf0, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0x80, 0x1f, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x03, 0xff, 0xc0, 0x3f, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xff, 0xe0, 0x3f, - 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xf0, 0x7f, 0x80, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x1f, 0xff, 0xf9, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, - 0xff, 0xf0, 0x1f, 0xff, 0xf8, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x1f, 0xff, 0xfd, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xfc, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x7f, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x3f, 0xff, 0xff, 0xf3, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xfe, 0x3f, 0xff, 0xff, 0xf8, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x1f, 0xff, - 0xff, 0xfc, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x1f, 0xff, 0xff, 0xfc, 0x3f, 0xff, 0xff, - 0xef, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x03, 0xf8, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xfc, 0x00, - 0x00, 0x01, 0xf8, 0x00, 0x00, 0x00, 0x07, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x01, 0xf8, 0x00, 0x00, - 0x00, 0x07, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x00, 0x07, 0xff, 0xff, 0xf8, - 0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x00, 0x03, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x60, 0x00, - 0x00, 0x00, 0x03, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x01, 0xff, 0xff, - 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, - 0xff, 0xe0, 0x07, 0xff, 0xff, 0x80, 0x0f, 0xff, 0xff, 0xfc, 0x3f, 0xff, 0xe0, 0x07, 0xff, 0xff, - 0x80, 0x1f, 0xff, 0xff, 0xfc, 0x1f, 0xff, 0xc0, 0x07, 0xff, 0xff, 0x80, 0x1f, 0xff, 0xff, 0xf8, - 0x0f, 0xff, 0xc0, 0x0f, 0xff, 0xff, 0x00, 0x1f, 0xff, 0xff, 0xf8, 0x07, 0xff, 0x80, 0x0f, 0xff, - 0xff, 0x00, 0x3f, 0xff, 0xff, 0xf8, 0x03, 0xff, 0x80, 0x1f, 0xff, 0xff, 0x80, 0x3f, 0xff, 0xff, - 0xf0, 0x01, 0xff, 0xc0, 0x1f, 0xff, 0xff, 0xc0, 0x3f, 0xff, 0xff, 0xf0, 0x01, 0xff, 0xf0, 0x1f, - 0xff, 0xff, 0xf0, 0x7f, 0xff, 0xff, 0xf0, 0x03, 0xff, 0xf8, 0x3f, 0xff, 0xff, 0xf8, 0x7f, 0xff, - 0xff, 0xe0, 0x03, 0xff, 0xfc, 0x3f, 0xff, 0xff, 0xfc, 0xff, 0xff, 0xff, 0xe0, 0x07, 0xff, 0xfe, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x07, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, - 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, - 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xe0, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x7f, 0xff, 0x80, 0x00, 0xff, 0xff, 0xff, 0xe0, 0x3f, 0xfe, 0x00, 0x7f, 0xff, 0x80, 0x03, 0xff, - 0xff, 0xff, 0xf8, 0xff, 0xfe, 0x00, 0xff, 0xff, 0xc0, 0x07, 0xff, 0xff, 0xff, 0xfd, 0xff, 0xfe, - 0x00, 0xff, 0xff, 0xc0, 0x0f, 0xff, 0xff, 0xff, 0xfd, 0xff, 0xfe, 0x00, 0xff, 0xff, 0xe0, 0x1f, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x01, 0xff, 0xff, 0xf0, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xfe, 0x01, 0xff, 0xff, 0xf8, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x01, 0xff, 0xff, 0xfc, - 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x01, 0xff, 0xff, 0xfe, 0x7f, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xfe, 0x03, 0xff, 0xff, 0xfe, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x03, 0xff, 0xff, - 0xff, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x03, 0xff, 0xff, 0xff, 0x9f, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0x03, 0xff, 0xff, 0xff, 0xef, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x81, 0xff, - 0xff, 0xff, 0xf7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x81, 0xff, 0xff, 0xff, 0xf9, 0xff, 0xff, - 0xbf, 0xff, 0xff, 0xff, 0xc1, 0xff, 0xff, 0xff, 0xfc, 0xff, 0xff, 0xbf, 0xff, 0xff, 0xff, 0xe0, - 0xff, 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x7f, 0xff, 0xff, 0xff, 0x9f, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x3f, 0xe7, 0xff, 0xff, 0xe7, 0xfd, 0xff, 0xff, 0xff, 0xff, - 0xfe, 0x00, 0x1f, 0xff, 0xff, 0xfc, 0x73, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x7f, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff -}; - -// Array of all bitmaps for convenience. (Total bytes used to store images in PROGMEM = 8032) -const int epd_icons_allArray_LEN = 4; -const unsigned char* epd_icons_allArray[epd_icons_allArray_LEN] = { - epd_icons_pickaxe, - epd_icons_rocket_launch, - epd_icons_lightning_bolt, - epd_icons_bitaxe_logo -}; diff --git a/src/icons/icons.h b/src/icons/icons.h deleted file mode 100644 index 136b4cc..0000000 --- a/src/icons/icons.h +++ /dev/null @@ -1,10 +0,0 @@ -#pragma once - -#ifndef ICONS_H -#define ICONS_H - -#include - -extern const unsigned char* epd_icons_allArray[]; - -#endif // ICONS_H diff --git a/src/lib/bitaxe_fetch.cpp b/src/lib/bitaxe_fetch.cpp deleted file mode 100644 index 8fa1db0..0000000 --- a/src/lib/bitaxe_fetch.cpp +++ /dev/null @@ -1,60 +0,0 @@ -#include "bitaxe_fetch.hpp" - -void BitAxeFetch::taskWrapper(void* pvParameters) { - BitAxeFetch::getInstance().task(); -} - -uint64_t BitAxeFetch::getHashRate() const { - return hashrate; -} - -uint64_t BitAxeFetch::getBestDiff() const { - return bestDiff; -} - -void BitAxeFetch::task() { - for (;;) { - ulTaskNotifyTake(pdTRUE, portMAX_DELAY); - - HTTPClient http; - http.setUserAgent(USER_AGENT); - String bitaxeApiUrl = "http://" + preferences.getString("bitaxeHostname", DEFAULT_BITAXE_HOSTNAME) + "/api/system/info"; - http.begin(bitaxeApiUrl.c_str()); - - int httpCode = http.GET(); - - if (httpCode == 200) { - String payload = http.getString(); - JsonDocument doc; - deserializeJson(doc, payload); - - // Convert GH/s to H/s (multiply by 10^9) - float hashRateGH = doc["hashRate"].as(); - hashrate = static_cast(std::round(hashRateGH * std::pow(10, getHashrateMultiplier('G')))); - - // Parse difficulty string and convert to uint64_t - std::string diffStr = doc["bestDiff"].as(); - char diffUnit = diffStr[diffStr.length() - 1]; - if (std::isalpha(diffUnit)) { - float diffValue = std::stof(diffStr.substr(0, diffStr.length() - 1)); - bestDiff = static_cast(std::round(diffValue * std::pow(10, getDifficultyMultiplier(diffUnit)))); - } else { - bestDiff = std::stoull(diffStr); - } - - if (workQueue != nullptr && (ScreenHandler::getCurrentScreen() == SCREEN_BITAXE_HASHRATE || ScreenHandler::getCurrentScreen() == SCREEN_BITAXE_BESTDIFF)) { - WorkItem priceUpdate = {TASK_BITAXE_UPDATE, 0}; - xQueueSend(workQueue, &priceUpdate, portMAX_DELAY); - } - } else { - Serial.print(F("Error retrieving BitAxe data. HTTP status code: ")); - Serial.println(httpCode); - Serial.println(bitaxeApiUrl); - } - } -} - -void BitAxeFetch::setup() { - xTaskCreate(taskWrapper, "bitaxeFetch", (3 * 1024), NULL, tskIDLE_PRIORITY, &taskHandle); - xTaskNotifyGive(taskHandle); -} \ No newline at end of file diff --git a/src/lib/bitaxe_fetch.hpp b/src/lib/bitaxe_fetch.hpp deleted file mode 100644 index 0dd98d9..0000000 --- a/src/lib/bitaxe_fetch.hpp +++ /dev/null @@ -1,34 +0,0 @@ -#pragma once - -#include -#include -#include - -#include "lib/config.hpp" -#include "lib/shared.hpp" - -class BitAxeFetch { -public: - static BitAxeFetch& getInstance() { - static BitAxeFetch instance; - return instance; - } - - void setup(); - uint64_t getHashRate() const; - uint64_t getBestDiff() const; - static void taskWrapper(void* pvParameters); - TaskHandle_t getTaskHandle() const { return taskHandle; } - -private: - BitAxeFetch() = default; - ~BitAxeFetch() = default; - BitAxeFetch(const BitAxeFetch&) = delete; - BitAxeFetch& operator=(const BitAxeFetch&) = delete; - - void task(); - - TaskHandle_t taskHandle = nullptr; - uint64_t hashrate = 0; - uint64_t bestDiff = 0; -}; \ No newline at end of file diff --git a/src/lib/block_notify.cpp b/src/lib/block_notify.cpp index 20e6267..904b6f3 100644 --- a/src/lib/block_notify.cpp +++ b/src/lib/block_notify.cpp @@ -1,325 +1,233 @@ #include "block_notify.hpp" -// Initialize static members -esp_websocket_client_handle_t BlockNotify::wsClient = nullptr; -uint32_t BlockNotify::currentBlockHeight = 878000; -uint16_t BlockNotify::blockMedianFee = 1; -bool BlockNotify::notifyInit = false; -unsigned long int BlockNotify::lastBlockUpdate = 0; -TaskHandle_t BlockNotify::taskHandle = nullptr; +char *wsServer; +esp_websocket_client_handle_t blockNotifyClient = NULL; +uint currentBlockHeight = 816000; +uint blockMedianFee = 1; +bool blockNotifyInit = false; -const char* BlockNotify::mempoolWsCert = R"EOF( ------BEGIN CERTIFICATE----- -MIIF3jCCA8agAwIBAgIQAf1tMPyjylGoG7xkDjUDLTANBgkqhkiG9w0BAQwFADCB -iDELMAkGA1UEBhMCVVMxEzARBgNVBAgTCk5ldyBKZXJzZXkxFDASBgNVBAcTC0pl -cnNleSBDaXR5MR4wHAYDVQQKExVUaGUgVVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNV -BAMTJVVTRVJUcnVzdCBSU0EgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMTAw -MjAxMDAwMDAwWhcNMzgwMTE4MjM1OTU5WjCBiDELMAkGA1UEBhMCVVMxEzARBgNV -BAgTCk5ldyBKZXJzZXkxFDASBgNVBAcTC0plcnNleSBDaXR5MR4wHAYDVQQKExVU -aGUgVVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNVBAMTJVVTRVJUcnVzdCBSU0EgQ2Vy -dGlmaWNhdGlvbiBBdXRob3JpdHkwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIK -AoICAQCAEmUXNg7D2wiz0KxXDXbtzSfTTK1Qg2HiqiBNCS1kCdzOiZ/MPans9s/B -3PHTsdZ7NygRK0faOca8Ohm0X6a9fZ2jY0K2dvKpOyuR+OJv0OwWIJAJPuLodMkY -tJHUYmTbf6MG8YgYapAiPLz+E/CHFHv25B+O1ORRxhFnRghRy4YUVD+8M/5+bJz/ -Fp0YvVGONaanZshyZ9shZrHUm3gDwFA66Mzw3LyeTP6vBZY1H1dat//O+T23LLb2 -VN3I5xI6Ta5MirdcmrS3ID3KfyI0rn47aGYBROcBTkZTmzNg95S+UzeQc0PzMsNT -79uq/nROacdrjGCT3sTHDN/hMq7MkztReJVni+49Vv4M0GkPGw/zJSZrM233bkf6 -c0Plfg6lZrEpfDKEY1WJxA3Bk1QwGROs0303p+tdOmw1XNtB1xLaqUkL39iAigmT -Yo61Zs8liM2EuLE/pDkP2QKe6xJMlXzzawWpXhaDzLhn4ugTncxbgtNMs+1b/97l -c6wjOy0AvzVVdAlJ2ElYGn+SNuZRkg7zJn0cTRe8yexDJtC/QV9AqURE9JnnV4ee -UB9XVKg+/XRjL7FQZQnmWEIuQxpMtPAlR1n6BB6T1CZGSlCBst6+eLf8ZxXhyVeE -Hg9j1uliutZfVS7qXMYoCAQlObgOK6nyTJccBz8NUvXt7y+CDwIDAQABo0IwQDAd -BgNVHQ4EFgQUU3m/WqorSs9UgOHYm8Cd8rIDZsswDgYDVR0PAQH/BAQDAgEGMA8G -A1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEMBQADggIBAFzUfA3P9wF9QZllDHPF -Up/L+M+ZBn8b2kMVn54CVVeWFPFSPCeHlCjtHzoBN6J2/FNQwISbxmtOuowhT6KO -VWKR82kV2LyI48SqC/3vqOlLVSoGIG1VeCkZ7l8wXEskEVX/JJpuXior7gtNn3/3 -ATiUFJVDBwn7YKnuHKsSjKCaXqeYalltiz8I+8jRRa8YFWSQEg9zKC7F4iRO/Fjs -8PRF/iKz6y+O0tlFYQXBl2+odnKPi4w2r78NBc5xjeambx9spnFixdjQg3IM8WcR -iQycE0xyNN+81XHfqnHd4blsjDwSXWXavVcStkNr/+XeTWYRUc+ZruwXtuhxkYze -Sf7dNXGiFSeUHM9h4ya7b6NnJSFd5t0dCy5oGzuCr+yDZ4XUmFF0sbmZgIn/f3gZ -XHlKYC6SQK5MNyosycdiyA5d9zZbyuAlJQG03RoHnHcAP9Dc1ew91Pq7P8yF1m9/ -qS3fuQL39ZeatTXaw2ewh0qpKJ4jjv9cJ2vhsE/zB+4ALtRZh8tSQZXq9EfX7mRB -VXyNWQKV3WKdwrnuWih0hKWbt5DHDAff9Yk2dDLWKMGwsAvgnEzDHNb842m1R0aB -L6KCq9NjRHDEjf8tM7qtj3u1cIiuPhnPQCjY/MiQu12ZIvVS5ljFH4gxQ+6IHdfG -jjxDah2nGN59PRbxYvnKkKj9 ------END CERTIFICATE----- +// const char *mempoolWsCert = R"(-----BEGIN CERTIFICATE----- +// MIIHfTCCBmWgAwIBAgIRANFX3mhqRYDt1NFuENoSyaAwDQYJKoZIhvcNAQELBQAw +// gZUxCzAJBgNVBAYTAkdCMRswGQYDVQQIExJHcmVhdGVyIE1hbmNoZXN0ZXIxEDAO +// BgNVBAcTB1NhbGZvcmQxGDAWBgNVBAoTD1NlY3RpZ28gTGltaXRlZDE9MDsGA1UE +// AxM0U2VjdGlnbyBSU0EgT3JnYW5pemF0aW9uIFZhbGlkYXRpb24gU2VjdXJlIFNl +// cnZlciBDQTAeFw0yMzA3MjQwMDAwMDBaFw0yNDA4MjIyMzU5NTlaMFcxCzAJBgNV +// BAYTAkpQMQ4wDAYDVQQIEwVUb2t5bzEgMB4GA1UEChMXTUVNUE9PTCBTUEFDRSBD +// Ty4sIExURC4xFjAUBgNVBAMTDW1lbXBvb2wuc3BhY2UwggEiMA0GCSqGSIb3DQEB +// AQUAA4IBDwAwggEKAoIBAQCqmiPRWgo58d25R0biQjAksXMq5ciH7z7ZQo2w2AbB +// rHxpnlIry74b9S4wRY5UJeYmd6ZwA76NdSioDvxTJc29bLplY+Ftmfc4ET0zYb2k +// Fi86z7GOWb6Ezor/qez9uMM9cxd021Bvcs0/2OrL6Sgp66u9keDZv9NyvFPpXfuR +// tdV2r4HF57VJqZn105PN4k80kNWgDbae8aw+BuUNvQYKEe71yfB7Bh6zSh9pCSfM +// I6pIJdQzoada2uY1dQMoJeIq8qKNKqAPKGsH5McemUT5ZIKU/tjk3nfX0pz/sQa4 +// CN7tLH6UeUlctei92GFd6Xtn7RbKLhDUbc4Sq02Cc9iXAgMBAAGjggQDMIID/zAf +// BgNVHSMEGDAWgBQX2dYlJ2f5McJJQ9kwNkSMbKlP6zAdBgNVHQ4EFgQUXkxoddJ6 +// rKobsbmDdtuCK1ywXuIwDgYDVR0PAQH/BAQDAgWgMAwGA1UdEwEB/wQCMAAwHQYD +// VR0lBBYwFAYIKwYBBQUHAwEGCCsGAQUFBwMCMEoGA1UdIARDMEEwNQYMKwYBBAGy +// MQECAQMEMCUwIwYIKwYBBQUHAgEWF2h0dHBzOi8vc2VjdGlnby5jb20vQ1BTMAgG +// BmeBDAECAjBaBgNVHR8EUzBRME+gTaBLhklodHRwOi8vY3JsLnNlY3RpZ28uY29t +// L1NlY3RpZ29SU0FPcmdhbml6YXRpb25WYWxpZGF0aW9uU2VjdXJlU2VydmVyQ0Eu +// Y3JsMIGKBggrBgEFBQcBAQR+MHwwVQYIKwYBBQUHMAKGSWh0dHA6Ly9jcnQuc2Vj +// dGlnby5jb20vU2VjdGlnb1JTQU9yZ2FuaXphdGlvblZhbGlkYXRpb25TZWN1cmVT +// ZXJ2ZXJDQS5jcnQwIwYIKwYBBQUHMAGGF2h0dHA6Ly9vY3NwLnNlY3RpZ28uY29t +// MIIBgAYKKwYBBAHWeQIEAgSCAXAEggFsAWoAdwB2/4g/Crb7lVHCYcz1h7o0tKTN +// uyncaEIKn+ZnTFo6dAAAAYmc9m/gAAAEAwBIMEYCIQD8XOozx411S/bnZambGjTB +// yTcr2fCmggUfQLSmqksD5gIhAIjiEMg0o1VSuQW31gWzfzL6idCkIZeSKN104cdp +// xa4SAHcA2ra/az+1tiKfm8K7XGvocJFxbLtRhIU0vaQ9MEjX+6sAAAGJnPZwPwAA +// BAMASDBGAiEA2sPTZTzvxewzQ8vk36+BWAKuJS7AvJ5W3clvfwCa8OUCIQC74ekT +// Ged2fqQE4sVy74aS6HRA2ihC9VLtNrASJx1YjQB2AO7N0GTV2xrOxVy3nbTNE6Iy +// h0Z8vOzew1FIWUZxH7WbAAABiZz2cA8AAAQDAEcwRQIgEklH7wYCFuuJIFUHX5PY +// /vZ3bDoxOp+061PT3caa+rICIQC0abgfGlBKiHxp47JZxnW3wcVqWdiYX4ViLm9H +// xfx4ljCBxgYDVR0RBIG+MIG7gg1tZW1wb29sLnNwYWNlghMqLmZtdC5tZW1wb29s +// LnNwYWNlghMqLmZyYS5tZW1wb29sLnNwYWNlgg8qLm1lbXBvb2wuc3BhY2WCEyou +// dGs3Lm1lbXBvb2wuc3BhY2WCEyoudmExLm1lbXBvb2wuc3BhY2WCDGJpc3EubWFy +// a2V0c4IKYmlzcS5uaW5qYYIObGlxdWlkLm5ldHdvcmuCDGxpcXVpZC5wbGFjZYIN +// bWVtcG9vbC5uaW5qYTANBgkqhkiG9w0BAQsFAAOCAQEAFvOSRnlHDfq9C8acjZEG +// 5XIqjNYigyWyjOvx83of6Z3PBKkAZB5D/UHBPp+jBDJiEb/QXC7Z7Y7kpuvnoVib +// b4jDc0RjGEsxL+3F7cSw26m3wILJhhHooGZRmFY4GOAeCZtYCOTzJsiZvFpDoQjU +// hTBxtaps05z0Ly9/eYvkXnjnBNROZJVR+KYHlq4TIoGNc4q4KvpfHv2I/vhS2M1e +// bECNNPEyRxHGKdXXO3huocE7aVKpy+JDR6cWwDu6hpdc1j/SCDqdTDFQ7McHOrqA +// fpPh4FcfePMh7Mqxtg2pSs5pXPtiP0ZjLgxd7HbAXct8Y+/jGk+k3sx3SeYXVimr +// ew== +// -----END CERTIFICATE-----)"; ------BEGIN CERTIFICATE----- -MIIFazCCA1OgAwIBAgIRAIIQz7DSQONZRGPgu2OCiwAwDQYJKoZIhvcNAQELBQAw -TzELMAkGA1UEBhMCVVMxKTAnBgNVBAoTIEludGVybmV0IFNlY3VyaXR5IFJlc2Vh -cmNoIEdyb3VwMRUwEwYDVQQDEwxJU1JHIFJvb3QgWDEwHhcNMTUwNjA0MTEwNDM4 -WhcNMzUwNjA0MTEwNDM4WjBPMQswCQYDVQQGEwJVUzEpMCcGA1UEChMgSW50ZXJu -ZXQgU2VjdXJpdHkgUmVzZWFyY2ggR3JvdXAxFTATBgNVBAMTDElTUkcgUm9vdCBY -MTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAK3oJHP0FDfzm54rVygc -h77ct984kIxuPOZXoHj3dcKi/vVqbvYATyjb3miGbESTtrFj/RQSa78f0uoxmyF+ -0TM8ukj13Xnfs7j/EvEhmkvBioZxaUpmZmyPfjxwv60pIgbz5MDmgK7iS4+3mX6U -A5/TR5d8mUgjU+g4rk8Kb4Mu0UlXjIB0ttov0DiNewNwIRt18jA8+o+u3dpjq+sW -T8KOEUt+zwvo/7V3LvSye0rgTBIlDHCNAymg4VMk7BPZ7hm/ELNKjD+Jo2FR3qyH -B5T0Y3HsLuJvW5iB4YlcNHlsdu87kGJ55tukmi8mxdAQ4Q7e2RCOFvu396j3x+UC -B5iPNgiV5+I3lg02dZ77DnKxHZu8A/lJBdiB3QW0KtZB6awBdpUKD9jf1b0SHzUv -KBds0pjBqAlkd25HN7rOrFleaJ1/ctaJxQZBKT5ZPt0m9STJEadao0xAH0ahmbWn -OlFuhjuefXKnEgV4We0+UXgVCwOPjdAvBbI+e0ocS3MFEvzG6uBQE3xDk3SzynTn -jh8BCNAw1FtxNrQHusEwMFxIt4I7mKZ9YIqioymCzLq9gwQbooMDQaHWBfEbwrbw -qHyGO0aoSCqI3Haadr8faqU9GY/rOPNk3sgrDQoo//fb4hVC1CLQJ13hef4Y53CI -rU7m2Ys6xt0nUW7/vGT1M0NPAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNV -HRMBAf8EBTADAQH/MB0GA1UdDgQWBBR5tFnme7bl5AFzgAiIyBpY9umbbjANBgkq -hkiG9w0BAQsFAAOCAgEAVR9YqbyyqFDQDLHYGmkgJykIrGF1XIpu+ILlaS/V9lZL -ubhzEFnTIZd+50xx+7LSYK05qAvqFyFWhfFQDlnrzuBZ6brJFe+GnY+EgPbk6ZGQ -3BebYhtF8GaV0nxvwuo77x/Py9auJ/GpsMiu/X1+mvoiBOv/2X/qkSsisRcOj/KK -NFtY2PwByVS5uCbMiogziUwthDyC3+6WVwW6LLv3xLfHTjuCvjHIInNzktHCgKQ5 -ORAzI4JMPJ+GslWYHb4phowim57iaztXOoJwTdwJx4nLCgdNbOhdjsnvzqvHu7Ur -TkXWStAmzOVyyghqpZXjFaH3pO3JLF+l+/+sKAIuvtd7u+Nxe5AW0wdeRlN8NwdC -jNPElpzVmbUq4JUagEiuTDkHzsxHpFKVK7q4+63SM1N95R1NbdWhscdCb+ZAJzVc -oyi3B43njTOQ5yOf+1CceWxG1bQVs5ZufpsMljq4Ui0/1lvh+wjChP4kqKOJ2qxq -4RgqsahDYVvTH9w7jXbyLeiNdd8XM2w9U/t7y0Ff/9yi0GE44Za4rF2LN9d11TPA -mRGunUHBcnWEvgJBQl9nJEiU0Zsnvgc/ubhPgXRR4Xq37Z0j4r7g1SgEEzwxA57d -emyPxgcYxn/eR44/KJ4EBs+lVDR3veyJm+kXQ99b21/+jh5Xos1AnX5iItreGCc= ------END CERTIFICATE----- -)EOF"; +void setupBlockNotify() { + // currentBlockHeight = preferences.getUInt("blockHeight", 816000); -void BlockNotify::onWebsocketEvent(void *handler_args, esp_event_base_t base, int32_t event_id, void *event_data) { - esp_websocket_event_data_t *data = (esp_websocket_event_data_t *)event_data; - BlockNotify& instance = BlockNotify::getInstance(); + IPAddress result; - switch (event_id) { - case WEBSOCKET_EVENT_CONNECTED: - { - notifyInit = true; - Serial.print(F("Connected to ")); - Serial.println(preferences.getString("mempoolInstance", DEFAULT_MEMPOOL_INSTANCE)); + int dnsErr = -1; + String mempoolInstance = + preferences.getString("mempoolInstance", DEFAULT_MEMPOOL_INSTANCE); - JsonDocument doc; - doc["action"] = "want"; - JsonArray dataArray = doc.createNestedArray("data"); - dataArray.add("blocks"); - dataArray.add("mempool-blocks"); - - String sub; - serializeJson(doc, sub); - esp_websocket_client_send_text(wsClient, sub.c_str(), sub.length(), portMAX_DELAY); - break; - } - case WEBSOCKET_EVENT_DATA: - instance.onWebsocketMessage(data); - break; + while (dnsErr != 1) { + dnsErr = WiFi.hostByName(mempoolInstance.c_str(), result); - case WEBSOCKET_EVENT_DISCONNECTED: - Serial.println(F("Mempool.space WS Connection Closed")); - break; - - case WEBSOCKET_EVENT_ERROR: - Serial.println(F("Mempool.space WS Connection Error")); - break; + if (dnsErr != 1) { + Serial.print(mempoolInstance); + Serial.println(F("mempool DNS could not be resolved")); + WiFi.reconnect(); + vTaskDelay(pdMS_TO_TICKS(1000)); } + } + + // Get current block height through regular API + HTTPClient *http = new HTTPClient(); + http->begin("https://" + mempoolInstance + "/api/blocks/tip/height"); + int httpCode = http->GET(); + + if (httpCode > 0 && httpCode == HTTP_CODE_OK) { + String blockHeightStr = http->getString(); + currentBlockHeight = blockHeightStr.toInt(); + // xTaskNotifyGive(blockUpdateTaskHandle); + if (workQueue != nullptr) { + WorkItem blockUpdate = {TASK_BLOCK_UPDATE, 0}; + xQueueSend(workQueue, &blockUpdate, portMAX_DELAY); + } + } + + // std::strcpy(wsServer, String("wss://" + mempoolInstance + + // "/api/v1/ws").c_str()); + + esp_websocket_client_config_t config = { + .uri = "wss://mempool.space/api/v1/ws", + // .task_stack = (6*1024), + // .cert_pem = mempoolWsCert, + .user_agent = USER_AGENT, + }; + + blockNotifyClient = esp_websocket_client_init(&config); + esp_websocket_register_events(blockNotifyClient, WEBSOCKET_EVENT_ANY, + onWebsocketEvent, blockNotifyClient); + esp_websocket_client_start(blockNotifyClient); } -void BlockNotify::onWebsocketMessage(esp_websocket_event_data_t *data) { - JsonDocument doc; - JsonDocument filter; - filter["block"]["height"] = true; - filter["mempool-blocks"][0]["medianFee"] = true; +void onWebsocketEvent(void *handler_args, esp_event_base_t base, + int32_t event_id, void *event_data) { + esp_websocket_event_data_t *data = (esp_websocket_event_data_t *)event_data; + const String sub = "{\"action\": \"want\", \"data\":[\"blocks\", \"mempool-blocks\"]}"; + switch (event_id) { + case WEBSOCKET_EVENT_CONNECTED: + blockNotifyInit = true; - deserializeJson(doc, (char*)data->data_ptr, DeserializationOption::Filter(filter)); + Serial.println(F("Connected to Mempool.space WebSocket")); - if (doc["block"].is()) { - JsonObject block = doc["block"]; - if (block["height"].as() != currentBlockHeight) { - processNewBlock(block["height"].as()); - } - } - else if (doc["mempool-blocks"].is()) { - JsonArray blockInfo = doc["mempool-blocks"].as(); - uint medianFee = (uint)round(blockInfo[0]["medianFee"].as()); - processNewBlockFee(medianFee); - } + Serial.println(sub); + if (esp_websocket_client_send_text(blockNotifyClient, sub.c_str(), + sub.length(), portMAX_DELAY) == -1) { + Serial.println(F("Mempool.space WS Block Subscribe Error")); + } + + break; + case WEBSOCKET_EVENT_DATA: + onWebsocketMessage(data); + break; + case WEBSOCKET_EVENT_ERROR: + Serial.println(F("Mempool.space WS Connnection error")); + break; + case WEBSOCKET_EVENT_DISCONNECTED: + Serial.println(F("Mempool.space WS Connnection Closed")); + break; + } } -void BlockNotify::setup() { - IPAddress result; - int dnsErr = -1; - String mempoolInstance = preferences.getString("mempoolInstance", DEFAULT_MEMPOOL_INSTANCE); +void onWebsocketMessage(esp_websocket_event_data_t *event_data) { + JsonDocument doc; - while (dnsErr != 1 && !strchr(mempoolInstance.c_str(), ':')) { - dnsErr = WiFi.hostByName(mempoolInstance.c_str(), result); - if (dnsErr != 1) { - Serial.print(mempoolInstance); - Serial.println(F("mempool DNS could not be resolved")); - WiFi.reconnect(); - vTaskDelay(pdMS_TO_TICKS(1000)); - } - } + JsonDocument filter; + filter["block"]["height"] = true; + filter["mempool-blocks"][0]["medianFee"] = true; - // Get current block height through regular API - int blockFetch = fetchLatestBlock(); + DeserializationError error = deserializeJson(doc, (char *)event_data->data_ptr, DeserializationOption::Filter(filter)); - if (blockFetch > currentBlockHeight) - currentBlockHeight = blockFetch; + // if (error) { + // Serial.print("deserializeJson() failed: "); + // Serial.println(error.c_str()); + // return; + // } - if (currentBlockHeight != -1) { - lastBlockUpdate = esp_timer_get_time() / 1000000; - } + if (doc.containsKey("block")) { + JsonObject block = doc["block"]; + + currentBlockHeight = block["height"].as(); + + //Serial.printf("New block found: %d\r\n", block["height"].as()); + preferences.putUInt("blockHeight", currentBlockHeight); if (workQueue != nullptr) { - WorkItem blockUpdate = {TASK_BLOCK_UPDATE, 0}; - xQueueSend(workQueue, &blockUpdate, portMAX_DELAY); - } + WorkItem blockUpdate = {TASK_BLOCK_UPDATE, 0}; + xQueueSend(workQueue, &blockUpdate, portMAX_DELAY); + // xTaskNotifyGive(blockUpdateTaskHandle); - const bool useSSL = preferences.getBool("mempoolSecure", DEFAULT_MEMPOOL_SECURE); - const String protocol = useSSL ? "wss" : "ws"; - String wsUri = protocol + "://" + mempoolInstance + "/api/v1/ws"; - - esp_websocket_client_config_t config = { - .task_stack = (6*1024), - .user_agent = USER_AGENT - }; - - if (useSSL) { - config.cert_pem = mempoolWsCert; - } - - config.uri = wsUri.c_str(); - - Serial.printf("Connecting to %s\r\n", mempoolInstance.c_str()); - - wsClient = esp_websocket_client_init(&config); - esp_websocket_register_events(wsClient, WEBSOCKET_EVENT_ANY, onWebsocketEvent, wsClient); - esp_websocket_client_start(wsClient); -} - - - -void BlockNotify::processNewBlock(uint32_t newBlockHeight) { - if (newBlockHeight <= currentBlockHeight) - { - return; - } - - currentBlockHeight = newBlockHeight; - lastBlockUpdate = esp_timer_get_time() / 1000000; - - if (workQueue != nullptr) - { - WorkItem blockUpdate = {TASK_BLOCK_UPDATE, 0}; - xQueueSend(workQueue, &blockUpdate, portMAX_DELAY); - } - - if (ScreenHandler::getCurrentScreen() != SCREEN_BLOCK_HEIGHT && - preferences.getBool("stealFocus", DEFAULT_STEAL_FOCUS)) - { + if (getCurrentScreen() != SCREEN_BLOCK_HEIGHT && + preferences.getBool("stealFocus", true)) { uint64_t timerPeriod = 0; - if (isTimerActive()) - { - timerPeriod = getTimerSeconds(); - esp_timer_stop(screenRotateTimer); + if (isTimerActive()) { + // store timer periode before making inactive to prevent artifacts + timerPeriod = getTimerSeconds(); + esp_timer_stop(screenRotateTimer); } - ScreenHandler::setCurrentScreen(SCREEN_BLOCK_HEIGHT); - if (timerPeriod > 0) - { - esp_timer_start_periodic(screenRotateTimer, + setCurrentScreen(SCREEN_BLOCK_HEIGHT); + if (timerPeriod > 0) { + esp_timer_start_periodic(screenRotateTimer, timerPeriod * usPerSecond); } - vTaskDelay(pdMS_TO_TICKS(315*NUM_SCREENS)); // Extra delay because of screen switching + } + + if (preferences.getBool("ledFlashOnUpd", false)) { + vTaskDelay(pdMS_TO_TICKS(250)); // Wait until screens are updated + queueLedEffect(LED_FLASH_BLOCK_NOTIFY); + } } + } else if (doc.containsKey("mempool-blocks")) { + JsonArray blockInfo = doc["mempool-blocks"].as(); - if (preferences.getBool("ledFlashOnUpd", DEFAULT_LED_FLASH_ON_UPD)) - { - vTaskDelay(pdMS_TO_TICKS(250)); // Wait until screens are updated - getLedHandler().queueEffect(LED_FLASH_BLOCK_NOTIFY); - } -} + uint medianFee = (uint)round(blockInfo[0]["medianFee"].as()); -void BlockNotify::processNewBlockFee(uint16_t newBlockFee) { - if (blockMedianFee == newBlockFee) - { - return; - } - - blockMedianFee = newBlockFee; - - if (workQueue != nullptr) - { - WorkItem blockUpdate = {TASK_FEE_UPDATE, 0}; - xQueueSend(workQueue, &blockUpdate, portMAX_DELAY); - } -} - -uint32_t BlockNotify::getBlockHeight() const { - return currentBlockHeight; -} - -void BlockNotify::setBlockHeight(uint32_t newBlockHeight) -{ - currentBlockHeight = newBlockHeight; -} - -uint16_t BlockNotify::getBlockMedianFee() const { - return blockMedianFee; -} - -void BlockNotify::setBlockMedianFee(uint16_t newBlockMedianFee) -{ - blockMedianFee = newBlockMedianFee; -} - -bool BlockNotify::isConnected() const -{ - if (wsClient == NULL) - return false; - return esp_websocket_client_is_connected(wsClient); -} - -bool BlockNotify::isInitialized() const -{ - return notifyInit; -} - -void BlockNotify::stop() -{ - if (wsClient == NULL) - return; - - esp_websocket_client_close(wsClient, portMAX_DELAY); - esp_websocket_client_stop(wsClient); - esp_websocket_client_destroy(wsClient); - wsClient = NULL; -} - -void BlockNotify::restart() -{ - stop(); - setup(); -} - -int BlockNotify::fetchLatestBlock() { - try { - String mempoolInstance = preferences.getString("mempoolInstance", DEFAULT_MEMPOOL_INSTANCE); - const String protocol = preferences.getBool("mempoolSecure", DEFAULT_MEMPOOL_SECURE) ? "https" : "http"; - String url = protocol + "://" + mempoolInstance + "/api/blocks/tip/height"; - - HTTPClient* http = HttpHelper::begin(url); - Serial.println("Fetching block height from " + url); - int httpCode = http->GET(); - - if (httpCode > 0 && httpCode == HTTP_CODE_OK) { - String blockHeightStr = http->getString(); - HttpHelper::end(http); - return blockHeightStr.toInt(); + if (blockMedianFee == medianFee) { + doc.clear(); + return; } - HttpHelper::end(http); - Serial.println("HTTP code" + String(httpCode)); - } catch (...) { - Serial.println(F("An exception occurred while trying to get the latest block")); - } - return 2203; // B-T-C + + // Serial.printf("New median fee: %d\r\n", medianFee); + blockMedianFee = medianFee; + + if (workQueue != nullptr) { + WorkItem blockUpdate = {TASK_FEE_UPDATE, 0}; + xQueueSend(workQueue, &blockUpdate, portMAX_DELAY); + } + } + + doc.clear(); } -uint BlockNotify::getLastBlockUpdate() const -{ - return lastBlockUpdate; +uint getBlockHeight() { return currentBlockHeight; } + +void setBlockHeight(uint newBlockHeight) { + currentBlockHeight = newBlockHeight; } -void BlockNotify::setLastBlockUpdate(uint lastUpdate) -{ - lastBlockUpdate = lastUpdate; +uint getBlockMedianFee() { return blockMedianFee; } + +void setBlockMedianFee(uint newBlockMedianFee) { + blockMedianFee = newBlockMedianFee; +} + +bool isBlockNotifyConnected() { + if (blockNotifyClient == NULL) return false; + return esp_websocket_client_is_connected(blockNotifyClient); +} + +bool getBlockNotifyInit() { + return blockNotifyInit; +} + +void stopBlockNotify() { + if (blockNotifyClient == NULL) return; + + esp_websocket_client_close(blockNotifyClient, portMAX_DELAY); + esp_websocket_client_stop(blockNotifyClient); + esp_websocket_client_destroy(blockNotifyClient); + + blockNotifyClient = NULL; } \ No newline at end of file diff --git a/src/lib/block_notify.hpp b/src/lib/block_notify.hpp index 15aabee..72d9500 100644 --- a/src/lib/block_notify.hpp +++ b/src/lib/block_notify.hpp @@ -5,61 +5,28 @@ #include #include #include + #include #include #include "lib/led_handler.hpp" #include "lib/screen_handler.hpp" -#include "lib/timers.hpp" #include "lib/shared.hpp" -class BlockNotify { -public: - static BlockNotify& getInstance() { - static BlockNotify instance; - return instance; - } +// using namespace websockets; - // Delete copy constructor and assignment operator - BlockNotify(const BlockNotify&) = delete; - void operator=(const BlockNotify&) = delete; +void setupBlockNotify(); - // Block notification setup and control - void setup(); - void stop(); - void restart(); - bool isConnected() const; - bool isInitialized() const; +void onWebsocketEvent(void *handler_args, esp_event_base_t base, + int32_t event_id, void *event_data); +void onWebsocketMessage(esp_websocket_event_data_t *event_data); - // Block height management - void setBlockHeight(uint32_t newBlockHeight); - uint32_t getBlockHeight() const; +void setBlockHeight(uint newBlockHeight); +uint getBlockHeight(); - // Block fee management - void setBlockMedianFee(uint16_t blockMedianFee); - uint16_t getBlockMedianFee() const; +void setBlockMedianFee(uint blockMedianFee); +uint getBlockMedianFee(); - // Block processing - void processNewBlock(uint32_t newBlockHeight); - void processNewBlockFee(uint16_t newBlockFee); - - // Block fetch and update tracking - int fetchLatestBlock(); - uint getLastBlockUpdate() const; - void setLastBlockUpdate(uint lastUpdate); - -private: - BlockNotify() = default; // Private constructor for singleton - - void setupTask(); - static void onWebsocketEvent(void *handler_args, esp_event_base_t base, int32_t event_id, void *event_data); - void onWebsocketMessage(esp_websocket_event_data_t *data); - - static const char* mempoolWsCert; - static esp_websocket_client_handle_t wsClient; - static uint32_t currentBlockHeight; - static uint16_t blockMedianFee; - static bool notifyInit; - static unsigned long int lastBlockUpdate; - static TaskHandle_t taskHandle; -}; \ No newline at end of file +bool isBlockNotifyConnected(); +void stopBlockNotify(); +bool getBlockNotifyInit(); \ No newline at end of file diff --git a/src/lib/button_handler.cpp b/src/lib/button_handler.cpp index bd4204d..a74b37b 100644 --- a/src/lib/button_handler.cpp +++ b/src/lib/button_handler.cpp @@ -1,110 +1,57 @@ #include "button_handler.hpp" -// Initialize static members -TaskHandle_t ButtonHandler::buttonTaskHandle = NULL; -ButtonState ButtonHandler::buttonStates[4] = {}; +TaskHandle_t buttonTaskHandle = NULL; +const TickType_t debounceDelay = pdMS_TO_TICKS(50); +TickType_t lastDebounceTime = 0; -#ifdef IS_BTCLOCK_V8 -#define BTN_1 256 -#define BTN_2 512 -#define BTN_3 1024 -#define BTN_4 2048 -#else -#define BTN_1 2048 -#define BTN_2 1024 -#define BTN_3 512 -#define BTN_4 256 -#endif +void buttonTask(void *parameter) { + while (1) { + ulTaskNotifyTake(pdTRUE, portMAX_DELAY); + std::lock_guard lock(mcpMutex); -void ButtonHandler::buttonTask(void *parameter) { - while (1) { - ulTaskNotifyTake(pdTRUE, portMAX_DELAY); - - TickType_t currentTime = xTaskGetTickCount(); - - std::lock_guard lock(mcpMutex); - - if (!digitalRead(MCP_INT_PIN)) { - uint16_t intFlags = mcp1.getInterruptFlagRegister(); - uint16_t intCap = mcp1.getInterruptCaptureRegister(); - - // Check button states - if (intFlags & BTN_1) handleButtonPress(0); - if (intFlags & BTN_2) handleButtonPress(1); - if (intFlags & BTN_3) handleButtonPress(2); - if (intFlags & BTN_4) handleButtonPress(3); - - // Check for button releases - for (int i = 0; i < 4; i++) { - if (buttonStates[i].isPressed) { - bool currentlyPressed = false; - switch (i) { - case 0: currentlyPressed = (intCap & BTN_1); break; - case 1: currentlyPressed = (intCap & BTN_2); break; - case 2: currentlyPressed = (intCap & BTN_3); break; - case 3: currentlyPressed = (intCap & BTN_4); break; - } - if (!currentlyPressed) { - handleButtonRelease(i); - } - } - } - } - - // Clear interrupt state - while (!digitalRead(MCP_INT_PIN)) { - mcp1.getInterruptCaptureRegister(); - delay(1); - } - } -} - -void ButtonHandler::handleButtonPress(int buttonIndex) { TickType_t currentTime = xTaskGetTickCount(); - ButtonState &state = buttonStates[buttonIndex]; - - if ((currentTime - state.lastPressTime) >= debounceDelay) { - state.isPressed = true; - state.lastPressTime = currentTime; - } -} + if ((currentTime - lastDebounceTime) >= debounceDelay) { + lastDebounceTime = currentTime; -void ButtonHandler::handleButtonRelease(int buttonIndex) { - ButtonState &state = buttonStates[buttonIndex]; - - if (!state.isPressed) return; // Ignore if button wasn't pressed - - state.isPressed = false; - handleSingleClick(buttonIndex); -} + if (!digitalRead(MCP_INT_PIN)) { + uint pin = mcp1.getLastInterruptPin(); -void ButtonHandler::handleSingleClick(int buttonIndex) { - switch (buttonIndex) { - case 0: + switch (pin) { + case 3: toggleTimerActive(); break; - case 1: - ScreenHandler::nextScreen(); + case 2: + nextScreen(); break; - case 2: - ScreenHandler::previousScreen(); + case 1: + previousScreen(); break; - case 3: - ScreenHandler::showSystemStatusScreen(); + case 0: + showSystemStatusScreen(); break; + } + } + mcp1.clearInterrupts(); + } else { } + // Very ugly, but for some reason this is necessary + while (!digitalRead(MCP_INT_PIN)) { + mcp1.clearInterrupts(); + } + } } -void IRAM_ATTR ButtonHandler::handleButtonInterrupt() { - BaseType_t xHigherPriorityTaskWoken = pdFALSE; - xTaskNotifyFromISR(buttonTaskHandle, 0, eNoAction, &xHigherPriorityTaskWoken); - if (xHigherPriorityTaskWoken == pdTRUE) { - portYIELD_FROM_ISR(); - } +void IRAM_ATTR handleButtonInterrupt() { + BaseType_t xHigherPriorityTaskWoken = pdFALSE; + xTaskNotifyFromISR(buttonTaskHandle, 0, eNoAction, &xHigherPriorityTaskWoken); + if (xHigherPriorityTaskWoken == pdTRUE) { + portYIELD_FROM_ISR(); + } } -void ButtonHandler::setup() { - xTaskCreate(buttonTask, "ButtonTask", 3072, NULL, tskIDLE_PRIORITY, - &buttonTaskHandle); - attachInterrupt(MCP_INT_PIN, handleButtonInterrupt, FALLING); +void setupButtonTask() { + xTaskCreate(buttonTask, "ButtonTask", 4096, NULL, tskIDLE_PRIORITY, + &buttonTaskHandle); // Create the FreeRTOS task + // Use interrupt instead of task + attachInterrupt(MCP_INT_PIN, handleButtonInterrupt, CHANGE); } diff --git a/src/lib/button_handler.hpp b/src/lib/button_handler.hpp index 17fab6b..03e1b36 100644 --- a/src/lib/button_handler.hpp +++ b/src/lib/button_handler.hpp @@ -4,51 +4,9 @@ #include "lib/screen_handler.hpp" #include "lib/shared.hpp" -#include "lib/timers.hpp" -// Track timing for each button -struct ButtonState { - TickType_t lastPressTime = 0; - TickType_t pressStartTime = 0; - bool isPressed = false; - uint8_t clickCount = 0; - bool longPressHandled = false; -}; +extern TaskHandle_t buttonTaskHandle; -class ButtonHandler { -private: - static const TickType_t debounceDelay = pdMS_TO_TICKS(50); - static const TickType_t doubleClickDelay = pdMS_TO_TICKS(1000); // Maximum time between clicks for double click - static const TickType_t longPressDelay = pdMS_TO_TICKS(1500); // Time to hold for long press - - static ButtonState buttonStates[4]; - static TaskHandle_t buttonTaskHandle; - - // Button handlers - static void handleButtonPress(int buttonIndex); - static void handleButtonRelease(int buttonIndex); - static void handleSingleClick(int buttonIndex); - static void handleDoubleClick(int buttonIndex); - static void handleLongPress(int buttonIndex); - - // Task function - static void buttonTask(void *pvParameters); - -public: - static void setup(); - static void IRAM_ATTR handleButtonInterrupt(); - static void suspendTask() { if (buttonTaskHandle != NULL) vTaskSuspend(buttonTaskHandle); } - static void resumeTask() { if (buttonTaskHandle != NULL) vTaskResume(buttonTaskHandle); } - - #ifdef IS_BTCLOCK_V8 - static const uint16_t BTN_1 = 256; - static const uint16_t BTN_2 = 512; - static const uint16_t BTN_3 = 1024; - static const uint16_t BTN_4 = 2048; - #else - static const uint16_t BTN_1 = 2048; - static const uint16_t BTN_2 = 1024; - static const uint16_t BTN_3 = 512; - static const uint16_t BTN_4 = 256; - #endif -}; +void buttonTask(void *pvParameters); +void IRAM_ATTR handleButtonInterrupt(); +void setupButtonTask(); diff --git a/src/lib/config.cpp b/src/lib/config.cpp index 908a5a6..98911e4 100644 --- a/src/lib/config.cpp +++ b/src/lib/config.cpp @@ -1,176 +1,95 @@ #include "config.hpp" -#include "led_handler.hpp" #define MAX_ATTEMPTS_WIFI_CONNECTION 20 -// zlib_turbo zt; - Preferences preferences; -MCP23017 mcp1(0x20); -#ifdef IS_BTCLOCK_V8 -MCP23017 mcp2(0x21); +Adafruit_MCP23X17 mcp1; +#ifdef IS_BTCLOCK_S3 +Adafruit_MCP23X17 mcp2; #endif - -#ifdef HAS_FRONTLIGHT -PCA9685 flArray(PCA_I2C_ADDR); -BH1750 bh1750; -bool hasLuxSensor = false; -#endif - -std::vector screenMappings; +std::vector screenNameMap(SCREEN_COUNT); std::mutex mcpMutex; -uint lastTimeSync; - -void addScreenMapping(int value, const char *name) -{ - screenMappings.push_back({value, name}); -} - -void setupDataSource() -{ - DataSourceType dataSource = getDataSource(); - bool zapNotifyEnabled = preferences.getBool("nostrZapNotify", DEFAULT_ZAP_NOTIFY_ENABLED); - - // Setup Nostr if it's either the data source or zap notifications are enabled - if (dataSource == NOSTR_SOURCE || zapNotifyEnabled) { - setupNostrNotify(dataSource == NOSTR_SOURCE, zapNotifyEnabled); - setupNostrTask(); - } - // Setup other data sources if Nostr is not the data source - if (dataSource != NOSTR_SOURCE) { - xTaskCreate(setupWebsocketClients, "setupWebsocketClients", 8192, NULL, - tskIDLE_PRIORITY, NULL); - } -} void setup() { setupPreferences(); setupHardware(); - - EPDManager::getInstance().initialize(); - if (preferences.getBool("ledTestOnPower", DEFAULT_LED_TEST_ON_POWER)) + setupDisplays(); + if (preferences.getBool("ledTestOnPower", true)) { - auto& ledHandler = getLedHandler(); - ledHandler.queueEffect(LED_POWER_TEST); + queueLedEffect(LED_POWER_TEST); } { std::lock_guard lockMcp(mcpMutex); - if (mcp1.read1(3) == LOW) + if (mcp1.digitalRead(3) == LOW) { preferences.putBool("wifiConfigured", false); preferences.remove("txPower"); WiFi.eraseAP(); - auto& ledHandler = getLedHandler(); - ledHandler.queueEffect(LED_EFFECT_WIFI_ERASE_SETTINGS); + queueLedEffect(LED_EFFECT_WIFI_ERASE_SETTINGS); } } { - if (mcp1.read1(0) == LOW) + if (mcp1.digitalRead(0) == LOW) { // Then loop forever to prevent anything else from writing to the screen - while (true) - { + while (true) { delay(1000); } } - else if (mcp1.read1(1) == LOW) - { - preferences.clear(); - auto& ledHandler = getLedHandler(); - ledHandler.queueEffect(LED_EFFECT_WIFI_ERASE_SETTINGS); - nvs_flash_erase(); - delay(1000); - - ESP.restart(); - } } - setupWifi(); - // loadIcons(); + tryImprovSetup(); setupWebserver(); - syncTime(); + // setupWifi(); + setupTime(); finishSetup(); setupTasks(); setupTimers(); - // Setup data sources (includes Nostr zap notifications if enabled) - setupDataSource(); + xTaskCreate(setupWebsocketClients, "setupWebsocketClients", 4096, NULL, + tskIDLE_PRIORITY, NULL); - if (preferences.getBool("bitaxeEnabled", DEFAULT_BITAXE_ENABLED)) - { - BitAxeFetch::getInstance().setup(); - } - - if (preferences.getBool("miningPoolStats", DEFAULT_MINING_POOL_STATS_ENABLED)) - { - MiningPoolStatsFetch::getInstance().setup(); - } - - ButtonHandler::setup(); + setupButtonTask(); setupOTA(); - EPDManager::getInstance().waitUntilNoneBusy(); - -#ifdef HAS_FRONTLIGHT - if (!preferences.getBool("flAlwaysOn", DEFAULT_FL_ALWAYS_ON)) - { - auto& ledHandler = getLedHandler(); - ledHandler.frontlightFadeOutAll(preferences.getUInt("flEffectDelay"), true); - flArray.allOFF(); - } -#endif - - EPDManager::getInstance().forceFullRefresh(); + waitUntilNoneBusy(); + forceFullRefresh(); } -void setupWifi() +void tryImprovSetup() { WiFi.onEvent(WiFiEvent); - - // wifi_country_t country = { - // .cc = "NL", - // .schan = 1, - // .nchan = 13, - // .policy = WIFI_COUNTRY_POLICY_MANUAL - // }; - - // esp_err_t err = esp_wifi_set_country(&country); - // if (err != ESP_OK) { - // Serial.printf("Failed to set country: %d\n", err); - // } - WiFi.setAutoConnect(true); WiFi.setAutoReconnect(true); WiFi.begin(); - - - - if (preferences.getInt("txPower", DEFAULT_TX_POWER)) + if (preferences.getInt("txPower", 0)) { if (WiFi.setTxPower( - static_cast(preferences.getInt("txPower", DEFAULT_TX_POWER)))) + static_cast(preferences.getInt("txPower", 0)))) { Serial.printf("WiFi max tx power set to %d\n", - preferences.getInt("txPower", DEFAULT_TX_POWER)); + preferences.getInt("txPower", 0)); } } - // if (!preferences.getBool("wifiConfigured", DEFAULT_WIFI_CONFIGURED) + // if (!preferences.getBool("wifiConfigured", false)) { - auto& ledHandler = getLedHandler(); - ledHandler.queueEffect(LED_EFFECT_WIFI_WAIT_FOR_CONFIG); + queueLedEffect(LED_EFFECT_WIFI_WAIT_FOR_CONFIG); + + uint8_t x_buffer[16]; + uint8_t x_position = 0; bool buttonPress = false; { std::lock_guard lockMcp(mcpMutex); - buttonPress = (mcp1.read1(2) == LOW); + buttonPress = (mcp1.digitalRead(2) == LOW); } { @@ -178,73 +97,90 @@ void setupWifi() byte mac[6]; WiFi.macAddress(mac); - String softAP_SSID = getMyHostname(); + String softAP_SSID = + String("BTClock" + String(mac[5], 16) + String(mac[1], 16)); WiFi.setHostname(softAP_SSID.c_str()); - String softAP_password = replaceAmbiguousChars( + String softAP_password = base64::encode(String(mac[2], 16) + String(mac[4], 16) + - String(mac[5], 16) + String(mac[1], 16) + String(mac[3], 16)) - .substring(2, 10)); + String(mac[5], 16) + String(mac[1], 16)) + .substring(2, 10); - wm.setConfigPortalTimeout(preferences.getUInt("wpTimeout", DEFAULT_WP_TIMEOUT)); + // wm.setConfigPortalTimeout(preferences.getUInt("wpTimeout", 600)); wm.setWiFiAutoReconnect(false); wm.setDebugOutput(false); - wm.setCountry("NL"); wm.setConfigPortalBlocking(true); wm.setAPCallback([&](WiFiManager *wifiManager) { - Serial.printf("Entered config mode:ip=%s, ssid='%s', pass='%s'\n", - WiFi.softAPIP().toString().c_str(), - wifiManager->getConfigPortalSSID().c_str(), - softAP_password.c_str()); + // Serial.printf("Entered config mode:ip=%s, ssid='%s', pass='%s'\n", + // WiFi.softAPIP().toString().c_str(), + // wifiManager->getConfigPortalSSID().c_str(), + // softAP_password.c_str()); // delay(6000); - EPDManager::getInstance().setForegroundColor(GxEPD_BLACK); - EPDManager::getInstance().setBackgroundColor(GxEPD_WHITE); + setFgColor(GxEPD_BLACK); + setBgColor(GxEPD_WHITE); const String qrText = "qrWIFI:S:" + wifiManager->getConfigPortalSSID() + ";T:WPA;P:" + softAP_password.c_str() + ";;"; const String explainText = "*SSID: *\r\n" + wifiManager->getConfigPortalSSID() + - "\r\n\r\n*Password:*\r\n" + softAP_password + - "\r\n\r\n*Hostname*:\r\n" + getMyHostname(); - // Set the UNIX timestamp - time_t timestamp = LAST_BUILD_TIME; // Example timestamp: March 7, 2021 00:00:00 UTC - - // Convert the timestamp to a struct tm in UTC - struct tm *timeinfo = gmtime(×tamp); - - // Format the date - char formattedDate[20]; - strftime(formattedDate, sizeof(formattedDate), "%y-%m-%d\r\n%H:%M:%S", timeinfo); - String hwStr = String(HW_REV); - hwStr.replace("_EPD_", "\r\nEPD_"); + "\r\n\r\n*Password:*\r\n" + softAP_password; std::array epdContent = { "Welcome!", "Bienvenidos!", "To setup\r\nscan QR or\r\nconnect\r\nmanually", "Para\r\nconfigurar\r\nescanear QR\r\no conectar\r\nmanualmente", explainText, - "*HW version:*\r\n" + hwStr + -#ifdef GIT_TAG - "\r\n\r\n*SW Version:*\r\n" + GIT_TAG + -#endif - "\r\n\r\n*FW build date:*\r\n" + formattedDate, + "*Hostname*:\r\n" + getMyHostname(), qrText}; - - EPDManager::getInstance().setContent(epdContent); }); + setEpdContent(epdContent); }); wm.setSaveConfigCallback([]() { preferences.putBool("wifiConfigured", true); delay(1000); - // just restart after success + // just restart after succes ESP.restart(); }); bool ac = wm.autoConnect(softAP_SSID.c_str(), softAP_password.c_str()); - } - EPDManager::getInstance().setForegroundColor(preferences.getUInt("fgColor", isWhiteVersion() ? GxEPD_BLACK : GxEPD_WHITE)); - EPDManager::getInstance().setBackgroundColor(preferences.getUInt("bgColor", isWhiteVersion() ? GxEPD_WHITE : GxEPD_BLACK)); + // waitUntilNoneBusy(); + // std::array epdContent = {"Welcome!", + // "Bienvenidos!", "Use\r\nweb-interface\r\nto configure", "Use\r\nla + // interfaz web\r\npara configurar", "Or + // restart\r\nwhile\r\nholding\r\n2nd button\r\r\nto start\r\n QR-config", + // "O reinicie\r\nmientras\r\n mantiene presionado\r\nel segundo + // botón\r\r\npara iniciar\r\nQR-config", ""}; setEpdContent(epdContent); + // esp_task_wdt_init(30, false); + // uint count = 0; + // while (WiFi.status() != WL_CONNECTED) + // { + // if (Serial.available() > 0) + // { + // uint8_t b = Serial.read(); + + // if (parse_improv_serial_byte(x_position, b, x_buffer, + // onImprovCommandCallback, onImprovErrorCallback)) + // { + // x_buffer[x_position++] = b; + // } + // else + // { + // x_position = 0; + // } + // } + // count++; + + // if (count > 2000000) { + // queueLedEffect(LED_EFFECT_HEARTBEAT); + // count = 0; + // } + // } + // esp_task_wdt_deinit(); + // esp_task_wdt_reset(); + } + setFgColor(preferences.getUInt("fgColor", DEFAULT_FG_COLOR)); + setBgColor(preferences.getUInt("bgColor", DEFAULT_BG_COLOR)); } // else // { @@ -257,149 +193,49 @@ void setupWifi() // queueLedEffect(LED_EFFECT_WIFI_CONNECT_SUCCESS); } -void syncTime() +void setupTime() { - configTime(0, 0, + configTime(preferences.getInt("gmtOffset", TIME_OFFSET_SECONDS), 0, NTP_SERVER); struct tm timeinfo; while (!getLocalTime(&timeinfo)) { - auto& ledHandler = getLedHandler(); - ledHandler.queueEffect(LED_EFFECT_CONFIGURING); - configTime(0, 0, + configTime(preferences.getInt("gmtOffset", TIME_OFFSET_SECONDS), 0, NTP_SERVER); delay(500); Serial.println(F("Retry set time")); } - - setTimezone(get_timezone_value_string(timezone_data::find_timezone_value(preferences.getString("tzString", DEFAULT_TZ_STRING)))); - - lastTimeSync = esp_timer_get_time() / 1000000; } -void setTimezone(String timezone) { - Serial.printf(" Setting Timezone to %s\n",timezone.c_str()); - setenv("TZ",timezone.c_str(),1); // Now adjust the TZ. Clock settings are adjusted to show the new local time - tzset(); -} - - void setupPreferences() { preferences.begin("btclock", false); - EPDManager::getInstance().setForegroundColor(preferences.getUInt("fgColor", DEFAULT_FG_COLOR)); - EPDManager::getInstance().setBackgroundColor(preferences.getUInt("bgColor", DEFAULT_BG_COLOR)); - BlockNotify::getInstance().setBlockHeight(preferences.getUInt("blockHeight", INITIAL_BLOCK_HEIGHT)); - setPrice(preferences.getUInt("lastPrice", INITIAL_LAST_PRICE), CURRENCY_USD); + setFgColor(preferences.getUInt("fgColor", DEFAULT_FG_COLOR)); + setBgColor(preferences.getUInt("bgColor", DEFAULT_BG_COLOR)); + setBlockHeight(preferences.getUInt("blockHeight", 816000)); + setPrice(preferences.getUInt("lastPrice", 30000)); - if (!preferences.isKey("enableDebugLog")) { - preferences.putBool("enableDebugLog", DEFAULT_ENABLE_DEBUG_LOG); - } - - if (!preferences.isKey("dataSource")) { - preferences.putUChar("dataSource", DEFAULT_DATA_SOURCE); - } - - // Initialize custom endpoint settings if not set - if (!preferences.isKey("customEndpoint")) { - preferences.putString("customEndpoint", DEFAULT_CUSTOM_ENDPOINT); - } - - if (!preferences.isKey("customEndpointDisableSSL")) { - preferences.putBool("customEndpointDisableSSL", DEFAULT_CUSTOM_ENDPOINT_DISABLE_SSL); - } - - // Set currency based on data source - DataSourceType dataSource = static_cast(preferences.getUChar("dataSource", DEFAULT_DATA_SOURCE)); - if (dataSource == BTCLOCK_SOURCE || dataSource == CUSTOM_SOURCE) { - ScreenHandler::setCurrentCurrency(preferences.getUChar("lastCurrency", CURRENCY_USD)); - } else { - ScreenHandler::setCurrentCurrency(CURRENCY_USD); - } - - if (!preferences.isKey("flDisable")) { - preferences.putBool("flDisable", isWhiteVersion() ? false : true); - } - - if (!preferences.isKey("gitReleaseUrl")) { - preferences.putString("gitReleaseUrl", DEFAULT_GIT_RELEASE_URL); - } - - if (!preferences.isKey("fgColor")) { - preferences.putUInt("fgColor", isWhiteVersion() ? GxEPD_BLACK : GxEPD_WHITE); - preferences.putUInt("bgColor", isWhiteVersion() ? GxEPD_WHITE : GxEPD_BLACK); - } - - - addScreenMapping(SCREEN_BLOCK_HEIGHT, "Block Height"); - - addScreenMapping(SCREEN_TIME, "Time"); - addScreenMapping(SCREEN_HALVING_COUNTDOWN, "Halving countdown"); - addScreenMapping(SCREEN_BLOCK_FEE_RATE, "Block Fee Rate"); - - addScreenMapping(SCREEN_SATS_PER_CURRENCY, "Sats per dollar"); - addScreenMapping(SCREEN_BTC_TICKER, "Ticker"); - addScreenMapping(SCREEN_MARKET_CAP, "Market Cap"); - - // addScreenMapping(SCREEN_SATS_PER_CURRENCY_USD, "Sats per USD"); - // addScreenMapping(SCREEN_BTC_TICKER_USD, "Ticker USD"); - // addScreenMapping(SCREEN_MARKET_CAP_USD, "Market Cap USD"); - - // addScreenMapping(SCREEN_SATS_PER_CURRENCY_EUR, "Sats per EUR"); - // addScreenMapping(SCREEN_BTC_TICKER_EUR, "Ticker EUR"); - // addScreenMapping(SCREEN_MARKET_CAP_EUR, "Market Cap EUR"); - - // screenNameMap[SCREEN_BLOCK_HEIGHT] = "Block Height"; - // screenNameMap[SCREEN_BLOCK_FEE_RATE] = "Block Fee Rate"; - // screenNameMap[SCREEN_SATS_PER_CURRENCY] = "Sats per dollar"; - // screenNameMap[SCREEN_BTC_TICKER] = "Ticker"; - // screenNameMap[SCREEN_TIME] = "Time"; - // screenNameMap[SCREEN_HALVING_COUNTDOWN] = "Halving countdown"; - // screenNameMap[SCREEN_MARKET_CAP] = "Market Cap"; - - // addCurrencyMappings(getActiveCurrencies()); - - if (preferences.getBool("bitaxeEnabled", DEFAULT_BITAXE_ENABLED)) - { - addScreenMapping(SCREEN_BITAXE_HASHRATE, "BitAxe Hashrate"); - addScreenMapping(SCREEN_BITAXE_BESTDIFF, "BitAxe Best Difficulty"); - } - - if (preferences.getBool("miningPoolStats", DEFAULT_MINING_POOL_STATS_ENABLED)) - { - addScreenMapping(SCREEN_MINING_POOL_STATS_HASHRATE, "Mining Pool Hashrate"); - if (MiningPoolStatsFetch::getInstance().getPool()->supportsDailyEarnings()) { - addScreenMapping(SCREEN_MINING_POOL_STATS_EARNINGS, "Mining Pool Earnings"); - } - } -} - -String replaceAmbiguousChars(String input) -{ - const char *ambiguous = "1IlO0"; - const char *replacements = "LKQM8"; - - for (int i = 0; i < strlen(ambiguous); i++) - { - input.replace(ambiguous[i], replacements[i]); - } - - return input; + screenNameMap[SCREEN_BLOCK_HEIGHT] = "Block Height"; + screenNameMap[SCREEN_BLOCK_FEE_RATE] = "Block Fee Rate"; + screenNameMap[SCREEN_MSCW_TIME] = "Sats per dollar"; + screenNameMap[SCREEN_BTC_TICKER] = "Ticker"; + screenNameMap[SCREEN_TIME] = "Time"; + screenNameMap[SCREEN_HALVING_COUNTDOWN] = "Halving countdown"; + screenNameMap[SCREEN_MARKET_CAP] = "Market Cap"; } void setupWebsocketClients(void *pvParameters) { - DataSourceType dataSource = getDataSource(); - - if (dataSource == BTCLOCK_SOURCE || dataSource == CUSTOM_SOURCE) + setupBlockNotify(); + + if (preferences.getBool("fetchEurPrice", false)) { - V2Notify::setupV2Notify(); + setupPriceFetchTask(); } - else if (dataSource == THIRD_PARTY_SOURCE) + else { - BlockNotify::getInstance().setup(); setupPriceNotify(); } @@ -416,27 +252,26 @@ void setupTimers() void finishSetup() { - auto& ledHandler = getLedHandler(); - if (preferences.getBool("ledStatus", DEFAULT_LED_STATUS)) + if (preferences.getBool("ledStatus", false)) { - ledHandler.restoreLedState(); + restoreLedState(); } else { - ledHandler.clear(); + clearLeds(); } } -std::vector getScreenNameMap() { return screenMappings; } +std::vector getScreenNameMap() { return screenNameMap; } void setupMcp() { -#ifdef IS_BTCLOCK_V8 +#ifdef IS_BTCLOCK_S3 const int mcp1AddrPins[] = {MCP1_A0_PIN, MCP1_A1_PIN, MCP1_A2_PIN}; const int mcp1AddrValues[] = {LOW, LOW, LOW}; const int mcp2AddrPins[] = {MCP2_A0_PIN, MCP2_A1_PIN, MCP2_A2_PIN}; - const int mcp2AddrValues[] = {HIGH, LOW, LOW}; + const int mcp2AddrValues[] = {LOW, LOW, HIGH}; pinMode(MCP_RESET_PIN, OUTPUT); digitalWrite(MCP_RESET_PIN, HIGH); @@ -463,18 +298,12 @@ void setupHardware() Serial.println(F("An Error has occurred while mounting LittleFS")); } - if (HW_REV == "REV_B_EPD_2_13" && !isWhiteVersion()) { - Serial.println(F("Black Rev B")); - } - if (!LittleFS.open("/index.html.gz", "r")) { - Serial.println(F("Error loading WebUI")); + Serial.println("Error loading WebUI"); } - // Initialize LED handler - auto& ledHandler = getLedHandler(); - ledHandler.setup(); + setupLeds(); WiFi.setHostname(getMyHostname().c_str()); if (!psramInit()) @@ -486,102 +315,279 @@ void setupHardware() Wire.begin(I2C_SDA_PIN, I2C_SCK_PIN, 400000); - if (!mcp1.begin()) { - Serial.println(F("Error MCP23017 1")); - } else { + if (!mcp1.begin_I2C(0x20)) + { + Serial.println(F("Error MCP23017")); + + // while (1) + // ; + } + else + { pinMode(MCP_INT_PIN, INPUT_PULLUP); - - // Enable mirrored interrupts (both INTA and INTB pins signal any interrupt) - if (!mcp1.mirrorInterrupts(true)) { - Serial.println(F("Error setting up mirrored interrupts")); - } + mcp1.setupInterrupts(false, false, LOW); - // Configure all 4 button pins as inputs with pullups and interrupts - for (int i = 0; i < 4; i++) { - if (!mcp1.pinMode1(i, INPUT_PULLUP)) { - Serial.printf("Error setting pin %d to input pull up\n", i); - } - // Enable interrupt on CHANGE for each pin - if (!mcp1.enableInterrupt(i, CHANGE)) { - Serial.printf("Error enabling interrupt for pin %d\n", i); - } + for (int i = 0; i < 4; i++) + { + mcp1.pinMode(i, INPUT_PULLUP); + mcp1.setupInterruptPin(i, LOW); } - - // Set interrupt pins as open drain with active-low polarity - if (!mcp1.setInterruptPolarity(2)) { // 2 = Open drain - Serial.println(F("Error setting interrupt polarity")); +#ifndef IS_BTCLOCK_S3 + for (int i = 8; i <= 14; i++) + { + mcp1.pinMode(i, OUTPUT); } - - // Clear any pending interrupts - mcp1.getInterruptCaptureRegister(); +#endif } -#ifdef IS_HW_REV_B - pinMode(39, INPUT_PULLDOWN); - -#endif - -#ifdef IS_BTCLOCK_V8 - if (!mcp2.begin()) +#ifdef IS_BTCLOCK_S3 + if (!mcp2.begin_I2C(0x21)) { - Serial.println(F("Error MCP23017 2")); + Serial.println(F("Error MCP23017")); // while (1) // ; } #endif +} -#ifdef HAS_FRONTLIGHT - // Initialize frontlight through LedHandler - ledHandler.initializeFrontlight(); +void improvGetAvailableWifiNetworks() +{ + int networkNum = WiFi.scanNetworks(); - Wire.beginTransmission(0x5C); - byte error = Wire.endTransmission(); - - if (error == 0) + for (int id = 0; id < networkNum; ++id) { - Serial.println(F("Found BH1750")); - hasLuxSensor = true; - bh1750.begin(BH1750::CONTINUOUS_HIGH_RES_MODE, 0x5C); + std::vector data = improv::build_rpc_response( + improv::GET_WIFI_NETWORKS, + {WiFi.SSID(id), String(WiFi.RSSI(id)), + (WiFi.encryptionType(id) == WIFI_AUTH_OPEN ? "NO" : "YES")}, + false); + improv_send_response(data); } - else + // final response + std::vector data = improv::build_rpc_response( + improv::GET_WIFI_NETWORKS, std::vector{}, false); + improv_send_response(data); +} + +bool improv_connectWifi(std::string ssid, std::string password) +{ + uint8_t count = 0; + + WiFi.begin(ssid.c_str(), password.c_str()); + + while (WiFi.status() != WL_CONNECTED) { - Serial.println(F("BH1750 Not found")); - hasLuxSensor = false; + blinkDelay(500, 2); + + if (count > MAX_ATTEMPTS_WIFI_CONNECTION) + { + WiFi.disconnect(); + return false; + } + count++; } -#endif + + return true; +} + +void onImprovErrorCallback(improv::Error err) +{ + blinkDelayColor(100, 1, 255, 0, 0); + // pixels.setPixelColor(0, pixels.Color(255, 0, 0)); + // pixels.setPixelColor(1, pixels.Color(255, 0, 0)); + // pixels.setPixelColor(2, pixels.Color(255, 0, 0)); + // pixels.setPixelColor(3, pixels.Color(255, 0, 0)); + // pixels.show(); + // vTaskDelay(pdMS_TO_TICKS(100)); + + // pixels.clear(); + // pixels.show(); + // vTaskDelay(pdMS_TO_TICKS(100)); +} + +std::vector getLocalUrl() +{ + return {// URL where user can finish onboarding or use device + // Recommended to use website hosted by device + String("http://" + WiFi.localIP().toString()).c_str()}; +} + +bool onImprovCommandCallback(improv::ImprovCommand cmd) +{ + switch (cmd.command) + { + case improv::Command::GET_CURRENT_STATE: + { + if ((WiFi.status() == WL_CONNECTED)) + { + improv_set_state(improv::State::STATE_PROVISIONED); + std::vector data = improv::build_rpc_response( + improv::GET_CURRENT_STATE, getLocalUrl(), false); + improv_send_response(data); + } + else + { + improv_set_state(improv::State::STATE_AUTHORIZED); + } + + break; + } + + case improv::Command::WIFI_SETTINGS: + { + if (cmd.ssid.length() == 0) + { + improv_set_error(improv::Error::ERROR_INVALID_RPC); + break; + } + + improv_set_state(improv::STATE_PROVISIONING); + queueLedEffect(LED_EFFECT_WIFI_CONNECTING); + + if (improv_connectWifi(cmd.ssid, cmd.password)) + { + queueLedEffect(LED_EFFECT_WIFI_CONNECT_SUCCESS); + + // std::array epdContent = {"S", "U", "C", "C", + // "E", "S", "S"}; setEpdContent(epdContent); + + preferences.putBool("wifiConfigured", true); + + improv_set_state(improv::STATE_PROVISIONED); + std::vector data = improv::build_rpc_response( + improv::WIFI_SETTINGS, getLocalUrl(), false); + improv_send_response(data); + + delay(2500); + ESP.restart(); + setupWebserver(); + } + else + { + queueLedEffect(LED_EFFECT_WIFI_CONNECT_ERROR); + + improv_set_state(improv::STATE_STOPPED); + improv_set_error(improv::Error::ERROR_UNABLE_TO_CONNECT); + } + + break; + } + + case improv::Command::GET_DEVICE_INFO: + { + std::vector infos = {// Firmware name + "BTClock", + // Firmware version + "1.0.0", + // Hardware chip/variant + "ESP32S3", + // Device name + "BTClock"}; + std::vector data = + improv::build_rpc_response(improv::GET_DEVICE_INFO, infos, false); + improv_send_response(data); + break; + } + + case improv::Command::GET_WIFI_NETWORKS: + { + improvGetAvailableWifiNetworks(); + // std::array epdContent = {"W", "E", "B", "W", "I", + // "F", "I"}; setEpdContent(epdContent); + break; + } + + default: + { + improv_set_error(improv::ERROR_UNKNOWN_RPC); + return false; + } + } + + return true; +} + +void improv_set_state(improv::State state) +{ + std::vector data = {'I', 'M', 'P', 'R', 'O', 'V'}; + data.resize(11); + data[6] = improv::IMPROV_SERIAL_VERSION; + data[7] = improv::TYPE_CURRENT_STATE; + data[8] = 1; + data[9] = state; + + uint8_t checksum = 0x00; + for (uint8_t d : data) + checksum += d; + data[10] = checksum; + + Serial.write(data.data(), data.size()); +} + +void improv_send_response(std::vector &response) +{ + std::vector data = {'I', 'M', 'P', 'R', 'O', 'V'}; + data.resize(9); + data[6] = improv::IMPROV_SERIAL_VERSION; + data[7] = improv::TYPE_RPC_RESPONSE; + data[8] = response.size(); + data.insert(data.end(), response.begin(), response.end()); + + uint8_t checksum = 0x00; + for (uint8_t d : data) + checksum += d; + data.push_back(checksum); + + Serial.write(data.data(), data.size()); +} + +void improv_set_error(improv::Error error) +{ + std::vector data = {'I', 'M', 'P', 'R', 'O', 'V'}; + data.resize(11); + data[6] = improv::IMPROV_SERIAL_VERSION; + data[7] = improv::TYPE_ERROR_STATE; + data[8] = 1; + data[9] = error; + + uint8_t checksum = 0x00; + for (uint8_t d : data) + checksum += d; + data[10] = checksum; + + Serial.write(data.data(), data.size()); } void WiFiEvent(WiFiEvent_t event, WiFiEventInfo_t info) { static bool first_connect = true; - auto& ledHandler = getLedHandler(); // Get ledHandler reference once at the start Serial.printf("[WiFi-event] event: %d\n", event); switch (event) { case ARDUINO_EVENT_WIFI_READY: - Serial.println(F("WiFi interface ready")); + Serial.println("WiFi interface ready"); break; case ARDUINO_EVENT_WIFI_SCAN_DONE: - Serial.println(F("Completed scan for access points")); + Serial.println("Completed scan for access points"); break; case ARDUINO_EVENT_WIFI_STA_START: - Serial.println(F("WiFi client started")); + Serial.println("WiFi client started"); break; case ARDUINO_EVENT_WIFI_STA_STOP: - Serial.println(F("WiFi clients stopped")); + Serial.println("WiFi clients stopped"); break; case ARDUINO_EVENT_WIFI_STA_CONNECTED: - Serial.println(F("Connected to access point")); + Serial.println("Connected to access point"); break; case ARDUINO_EVENT_WIFI_STA_DISCONNECTED: { if (!first_connect) { - Serial.println(F("Disconnected from WiFi access point")); - ledHandler.queueEffect(LED_EFFECT_WIFI_CONNECT_ERROR); + Serial.println("Disconnected from WiFi access point"); + queueLedEffect(LED_EFFECT_WIFI_CONNECT_ERROR); uint8_t reason = info.wifi_sta_disconnected.reason; if (reason) Serial.printf("Disconnect reason: %s, ", @@ -590,45 +596,45 @@ void WiFiEvent(WiFiEvent_t event, WiFiEventInfo_t info) break; } case ARDUINO_EVENT_WIFI_STA_AUTHMODE_CHANGE: - Serial.println(F("Authentication mode of access point has changed")); + Serial.println("Authentication mode of access point has changed"); break; case ARDUINO_EVENT_WIFI_STA_GOT_IP: { Serial.print("Obtained IP address: "); Serial.println(WiFi.localIP()); if (!first_connect) - ledHandler.queueEffect(LED_EFFECT_WIFI_CONNECT_SUCCESS); + queueLedEffect(LED_EFFECT_WIFI_CONNECT_SUCCESS); first_connect = false; break; } case ARDUINO_EVENT_WIFI_STA_LOST_IP: - Serial.println(F("Lost IP address and IP address is reset to 0")); - ledHandler.queueEffect(LED_EFFECT_WIFI_CONNECT_ERROR); + Serial.println("Lost IP address and IP address is reset to 0"); + queueLedEffect(LED_EFFECT_WIFI_CONNECT_ERROR); WiFi.reconnect(); break; case ARDUINO_EVENT_WIFI_AP_START: - Serial.println(F("WiFi access point started")); + Serial.println("WiFi access point started"); break; case ARDUINO_EVENT_WIFI_AP_STOP: - Serial.println(F("WiFi access point stopped")); + Serial.println("WiFi access point stopped"); break; case ARDUINO_EVENT_WIFI_AP_STACONNECTED: - Serial.println(F("Client connected")); + Serial.println("Client connected"); break; case ARDUINO_EVENT_WIFI_AP_STADISCONNECTED: - Serial.println(F("Client disconnected")); + Serial.println("Client disconnected"); break; case ARDUINO_EVENT_WIFI_AP_STAIPASSIGNED: - Serial.println(F("Assigned IP address to client")); + Serial.println("Assigned IP address to client"); break; case ARDUINO_EVENT_WIFI_AP_PROBEREQRECVED: - Serial.println(F("Received probe request")); + Serial.println("Received probe request"); break; case ARDUINO_EVENT_WIFI_AP_GOT_IP6: - Serial.println(F("AP IPv6 is preferred")); + Serial.println("AP IPv6 is preferred"); break; case ARDUINO_EVENT_WIFI_STA_GOT_IP6: - Serial.println(F("STA IPv6 is preferred")); + Serial.println("STA IPv6 is preferred"); break; default: break; @@ -641,141 +647,8 @@ String getMyHostname() // WiFi.macAddress(mac); esp_efuse_mac_get_default(mac); char hostname[15]; - String hostnamePrefix = preferences.getString("hostnamePrefix", DEFAULT_HOSTNAME_PREFIX); + String hostnamePrefix = preferences.getString("hostnamePrefix", "btclock"); snprintf(hostname, sizeof(hostname), "%s-%02x%02x%02x", hostnamePrefix, mac[3], mac[4], mac[5]); return hostname; -} - -uint getLastTimeSync() -{ - return lastTimeSync; -} - -#ifdef HAS_FRONTLIGHT - -float getLightLevel() -{ - return bh1750.readLightLevel(); -} - -bool hasLightLevel() -{ - return hasLuxSensor; -} -#endif - -String getHwRev() -{ -#ifndef HW_REV - return "REV_0"; -#else - return HW_REV; -#endif -} - -bool isWhiteVersion() -{ -#ifdef IS_HW_REV_B - pinMode(39, INPUT_PULLDOWN); - return digitalRead(39); -#else - return false; -#endif -} - -String getFsRev() -{ - File fsHash = LittleFS.open("/fs_hash.txt", "r"); - if (!fsHash) - { - Serial.println(F("Error loading WebUI")); - } - - String ret = fsHash.readString(); - fsHash.close(); - return ret; -} - -int findScreenIndexByValue(int value) -{ - for (int i = 0; i < screenMappings.size(); i++) - { - if (screenMappings[i].value == value) - { - return i; - } - } - return -1; // Return -1 if value is not found -} - -std::vector getAvailableCurrencies() -{ - return {CURRENCY_CODE_USD, CURRENCY_CODE_EUR, CURRENCY_CODE_GBP, CURRENCY_CODE_JPY, CURRENCY_CODE_AUD, CURRENCY_CODE_CAD}; -} - -std::vector getActiveCurrencies() -{ - std::vector result; - - // Convert Arduino String to std::string - std::string stdString = preferences.getString("actCurrencies", DEFAULT_ACTIVE_CURRENCIES).c_str(); - - // Use a stringstream to split the string - std::stringstream ss(stdString); - std::string item; - - // Split the string by comma and add each part to the vector - while (std::getline(ss, item, ',')) - { - result.push_back(item); - } - return result; -} - -bool isActiveCurrency(std::string ¤cy) -{ - std::vector ac = getActiveCurrencies(); - if (std::find(ac.begin(), ac.end(), currency) != ac.end()) - { - return true; - } - return false; -} - -const char* getFirmwareFilename() { - if (HW_REV == "REV_B_EPD_2_13") { - return "btclock_rev_b_213epd_firmware.bin"; - } else if (HW_REV == "REV_A_EPD_2_13") { - return "lolin_s3_mini_213epd_firmware.bin"; - } else if (HW_REV == "REV_A_EPD_2_9") { - return "lolin_s3_mini_29epd_firmware.bin"; - } else { - return ""; - } -} - -const char* getWebUiFilename() { - if (HW_REV == "REV_B_EPD_2_13") { - return "littlefs_8MB.bin"; - } else if (HW_REV == "REV_A_EPD_2_13") { - return "littlefs_4MB.bin"; - } else if (HW_REV == "REV_A_EPD_2_9") { - return "littlefs_4MB.bin"; - } else { - return "littlefs_4MB.bin"; - } -} - -bool debugLogEnabled() -{ - return preferences.getBool("enableDebugLog", DEFAULT_ENABLE_DEBUG_LOG); -} - -DataSourceType getDataSource() { - return static_cast(preferences.getUChar("dataSource", DEFAULT_DATA_SOURCE)); -} - -void setDataSource(DataSourceType source) { - preferences.putUChar("dataSource", static_cast(source)); -} +} \ No newline at end of file diff --git a/src/lib/config.hpp b/src/lib/config.hpp index c8d5336..cd4b262 100644 --- a/src/lib/config.hpp +++ b/src/lib/config.hpp @@ -1,108 +1,56 @@ #pragma once -#include +#include #include #include #include #include #include #include -#include + #include #include "lib/block_notify.hpp" #include "lib/button_handler.hpp" #include "lib/epd.hpp" -// #include "lib/improv.hpp" +#include "lib/improv.hpp" #include "lib/led_handler.hpp" #include "lib/ota.hpp" -#include "lib/nostr_notify.hpp" -#include "lib/bitaxe_fetch.hpp" -#include "lib/mining_pool_stats_fetch.hpp" - -#include "lib/v2_notify.hpp" - #include "lib/price_notify.hpp" #include "lib/screen_handler.hpp" #include "lib/shared.hpp" #include "lib/webserver.hpp" -#ifdef HAS_FRONTLIGHT -#include "PCA9685.h" -#include "BH1750.h" -#endif -#include "shared.hpp" -#include "defaults.hpp" -#include "timezone_data.hpp" #define NTP_SERVER "pool.ntp.org" -#define DEFAULT_TIME_OFFSET_SECONDS 3600 -#ifndef MCP_DEV_ADDR +#define DEFAULT_MEMPOOL_INSTANCE "mempool.space" +#define TIME_OFFSET_SECONDS 3600 +#define USER_AGENT "BTClock/2.0" #define MCP_DEV_ADDR 0x20 -#endif +#define DEFAULT_SECONDS_BETWEEN_PRICE_UPDATE 30 +#define DEFAULT_MINUTES_FULL_REFRESH 60 +#define DEFAULT_FG_COLOR GxEPD_WHITE +#define DEFAULT_BG_COLOR GxEPD_BLACK void setup(); -void syncTime(); -void setTimezone(String timezone); -uint getLastTimeSync(); +void setupTime(); void setupPreferences(); void setupWebsocketClients(void *pvParameters); void setupHardware(); -void setupWifi(); +void tryImprovSetup(); void setupTimers(); void finishSetup(); void setupMcp(); -#ifdef HAS_FRONTLIGHT -extern BH1750 bh1750; -extern bool hasLuxSensor; -float getLightLevel(); -bool hasLightLevel(); -#endif - String getMyHostname(); -std::vector getScreenNameMap(); +std::vector getScreenNameMap(); std::vector getLocalUrl(); -// bool improv_connectWifi(std::string ssid, std::string password); -// void improvGetAvailableWifiNetworks(); -// bool onImprovCommandCallback(improv::ImprovCommand cmd); -// void onImprovErrorCallback(improv::Error err); -// void improv_set_state(improv::State state); -// void improv_send_response(std::vector &response); -// void improv_set_error(improv::Error error); -//void addCurrencyMappings(const std::vector& currencies); -std::vector getActiveCurrencies(); -std::vector getAvailableCurrencies(); +bool improv_connectWifi(std::string ssid, std::string password); +void improvGetAvailableWifiNetworks(); +bool onImprovCommandCallback(improv::ImprovCommand cmd); +void onImprovErrorCallback(improv::Error err); +void improv_set_state(improv::State state); +void improv_send_response(std::vector &response); +void improv_set_error(improv::Error error); -bool isActiveCurrency(std::string ¤cy); - -void WiFiEvent(WiFiEvent_t event, WiFiEventInfo_t info); -String getHwRev(); -bool isWhiteVersion(); -String getFsRev(); - -bool debugLogEnabled(); - -void addScreenMapping(int value, const char* name); -// void addScreenMapping(int value, const String& name); -// void addScreenMapping(int value, const std::string& name); - -int findScreenIndexByValue(int value); -String replaceAmbiguousChars(String input); -const char* getFirmwareFilename(); -const char* getWebUiFilename(); -// void loadIcons(); - -extern Preferences preferences; -extern MCP23017 mcp1; -#ifdef IS_BTCLOCK_V8 -extern MCP23017 mcp2; -#endif - -#ifdef HAS_FRONTLIGHT -extern PCA9685 flArray; -#endif - -// Expose DataSourceType enum -extern DataSourceType getDataSource(); -extern void setDataSource(DataSourceType source); \ No newline at end of file +void WiFiEvent(WiFiEvent_t event, WiFiEventInfo_t info); \ No newline at end of file diff --git a/src/lib/defaults.hpp b/src/lib/defaults.hpp deleted file mode 100644 index a785561..0000000 --- a/src/lib/defaults.hpp +++ /dev/null @@ -1,103 +0,0 @@ -#pragma once - -#define INITIAL_BLOCK_HEIGHT 876600 -#define INITIAL_LAST_PRICE 50000 -#define DEFAULT_TX_POWER 0 - -#define DEFAULT_MEMPOOL_SECURE true -#define DEFAULT_LED_TEST_ON_POWER true -#define DEFAULT_LED_FLASH_ON_UPD false -#define DEFAULT_LED_BRIGHTNESS 128 -#define DEFAULT_STEAL_FOCUS false -#define DEFAULT_MCAP_BIG_CHAR true -#define DEFAULT_MDNS_ENABLED true -#define DEFAULT_OTA_ENABLED true -#define DEFAULT_FETCH_EUR_PRICE false -#define DEFAULT_USE_SATS_SYMBOL false -#define DEFAULT_USE_BLOCK_COUNTDOWN true -#define DEFAULT_SUFFIX_PRICE false -#define DEFAULT_DISABLE_LEDS false -#define DEFAULT_DISABLE_FL false -#define DEFAULT_MOW_MODE false -#define DEFAULT_SUFFIX_SHARE_DOT false - -#define DEFAULT_V2_SOURCE_CURRENCY CURRENCY_USD - -#define DEFAULT_TIME_OFFSET_SECONDS 3600 -#define DEFAULT_TZ_STRING "Europe/Amsterdam" - -#define DEFAULT_HOSTNAME_PREFIX "btclock" -#define DEFAULT_MEMPOOL_INSTANCE "mempool.space" - -#define DEFAULT_USE_NOSTR false -#define DEFAULT_NOSTR_NPUB "642317135fd4c4205323b9dea8af3270657e62d51dc31a657c0ec8aab31c6288" -#define DEFAULT_NOSTR_RELAY "wss://relay.primal.net" - -#define DEFAULT_SECONDS_BETWEEN_PRICE_UPDATE 30 -#define DEFAULT_MINUTES_FULL_REFRESH 60 - -#define DEFAULT_FG_COLOR GxEPD_WHITE -#define DEFAULT_BG_COLOR GxEPD_BLACK - -#define DEFAULT_WP_TIMEOUT 15*60 - -#define DEFAULT_FL_MAX_BRIGHTNESS 2048 -#define DEFAULT_FL_EFFECT_DELAY 15 - -#define DEFAULT_LUX_LIGHT_TOGGLE 128 -#define DEFAULT_FL_OFF_WHEN_DARK true - -#define DEFAULT_FL_ALWAYS_ON true -#define DEFAULT_FL_FLASH_ON_UPDATE true - -#define DEFAULT_LED_STATUS false -#define DEFAULT_TIMER_ACTIVE true -#define DEFAULT_TIMER_SECONDS 1800 -#define DEFAULT_CURRENT_SCREEN 0 - -#define DEFAULT_BITAXE_ENABLED false -#define DEFAULT_BITAXE_HOSTNAME "bitaxe1" - -#define DEFAULT_MINING_POOL_STATS_ENABLED false -#define DEFAULT_MINING_POOL_NAME "ocean" -#define DEFAULT_MINING_POOL_USER "38Qkkei3SuF1Eo45BaYmRHUneRD54yyTFy" // Random actual Ocean hasher -#define DEFAULT_LOCAL_POOL_ENDPOINT "umbrel.local:2019" - -#define DEFAULT_ZAP_NOTIFY_ENABLED false -#define DEFAULT_ZAP_NOTIFY_PUBKEY "b5127a08cf33616274800a4387881a9f98e04b9c37116e92de5250498635c422" -#define DEFAULT_LED_FLASH_ON_ZAP true -#define DEFAULT_FL_FLASH_ON_ZAP true -#define DEFAULT_FONT_NAME "antonio" - -#define DEFAULT_HTTP_AUTH_ENABLED false -#define DEFAULT_HTTP_AUTH_USERNAME "btclock" -#define DEFAULT_HTTP_AUTH_PASSWORD "satoshi" - -#define DEFAULT_ACTIVE_CURRENCIES "USD,EUR,JPY" - -#define DEFAULT_GIT_RELEASE_URL "https://git.btclock.dev/api/v1/repos/btclock/btclock_v3/releases/latest" -#define DEFAULT_VERTICAL_DESC true - -#define DEFAULT_MINING_POOL_LOGOS_URL "https://git.btclock.dev/btclock/mining-pool-logos/raw/branch/main" - -#define DEFAULT_ENABLE_DEBUG_LOG false - -#define DEFAULT_DISABLE_FL false -#define DEFAULT_CUSTOM_ENDPOINT "ws-staging.btclock.dev" -#define DEFAULT_CUSTOM_ENDPOINT_DISABLE_SSL false -#define DEFAULT_MOW_MODE false -#define DEFAULT_SCREEN_RESTORE_AFTER_ZAP true - -// Define data source types -enum DataSourceType { - BTCLOCK_SOURCE = 0, // BTClock's own data source - THIRD_PARTY_SOURCE = 1, // Third party data sources like mempool.space - NOSTR_SOURCE = 2, // Nostr data source - CUSTOM_SOURCE = 3 // Custom data source endpoint -}; - -#define DEFAULT_DATA_SOURCE BTCLOCK_SOURCE - -#ifndef DEFAULT_BOOT_TEXT -#define DEFAULT_BOOT_TEXT "BTCLOCK" -#endif \ No newline at end of file diff --git a/src/lib/epd.cpp b/src/lib/epd.cpp index fa389c6..0f4a229 100644 --- a/src/lib/epd.cpp +++ b/src/lib/epd.cpp @@ -1,537 +1,543 @@ #include "epd.hpp" -// Initialize static members -#ifdef IS_BTCLOCK_REV_B -Native_Pin EPDManager::EPD_DC(14); -std::array EPDManager::EPD_CS = { - Native_Pin(2), Native_Pin(4), Native_Pin(6), Native_Pin(10), - Native_Pin(38), Native_Pin(21), Native_Pin(17) +#ifndef IS_BTCLOCK_S3 +Native_Pin EPD_CS[NUM_SCREENS] = { + Native_Pin(2), + Native_Pin(4), + Native_Pin(6), + Native_Pin(10), + Native_Pin(33), + Native_Pin(21), + Native_Pin(17), +#if NUM_SCREENS == 9 + // MCP23X17_Pin(mcp2, 7), + Native_Pin(-1), + Native_Pin(-1), +#endif }; -std::array EPDManager::EPD_BUSY = { - Native_Pin(3), Native_Pin(5), Native_Pin(7), Native_Pin(9), - Native_Pin(37), Native_Pin(18), Native_Pin(16) +Native_Pin EPD_BUSY[NUM_SCREENS] = { + Native_Pin(3), + Native_Pin(5), + Native_Pin(7), + Native_Pin(9), + Native_Pin(37), + Native_Pin(18), + Native_Pin(16), }; -std::array EPDManager::EPD_RESET = { - MCP23X17_Pin(mcp1, 8), MCP23X17_Pin(mcp1, 9), MCP23X17_Pin(mcp1, 10), - MCP23X17_Pin(mcp1, 11), MCP23X17_Pin(mcp1, 12), MCP23X17_Pin(mcp1, 13), - MCP23X17_Pin(mcp1, 14) +MCP23X17_Pin EPD_RESET_MPD[NUM_SCREENS] = { + MCP23X17_Pin(mcp1, 8), + MCP23X17_Pin(mcp1, 9), + MCP23X17_Pin(mcp1, 10), + MCP23X17_Pin(mcp1, 11), + MCP23X17_Pin(mcp1, 12), + MCP23X17_Pin(mcp1, 13), + MCP23X17_Pin(mcp1, 14), }; -#elif defined(IS_BTCLOCK_V8) -Native_Pin EPDManager::EPD_DC(38); -std::array EPDManager::EPD_BUSY = { - MCP23X17_Pin(mcp1, 8), MCP23X17_Pin(mcp1, 9), MCP23X17_Pin(mcp1, 10), - MCP23X17_Pin(mcp1, 11), MCP23X17_Pin(mcp1, 12), MCP23X17_Pin(mcp1, 13), - MCP23X17_Pin(mcp1, 14), MCP23X17_Pin(mcp1, 4) + +Native_Pin EPD_DC = Native_Pin(14); +#else +Native_Pin EPD_DC = Native_Pin(38); + +MCP23X17_Pin EPD_BUSY[NUM_SCREENS] = { + MCP23X17_Pin(mcp1, 8), + MCP23X17_Pin(mcp1, 9), + MCP23X17_Pin(mcp1, 10), + MCP23X17_Pin(mcp1, 11), + MCP23X17_Pin(mcp1, 12), + MCP23X17_Pin(mcp1, 13), + MCP23X17_Pin(mcp1, 14), + MCP23X17_Pin(mcp1, 4), }; -std::array EPDManager::EPD_CS = { + +MCP23X17_Pin EPD_CS[NUM_SCREENS] = { MCP23X17_Pin(mcp2, 8), MCP23X17_Pin(mcp2, 10), MCP23X17_Pin(mcp2, 12), MCP23X17_Pin(mcp2, 14), MCP23X17_Pin(mcp2, 0), MCP23X17_Pin(mcp2, 2), - MCP23X17_Pin(mcp2, 4), MCP23X17_Pin(mcp2, 6) -}; -std::array EPDManager::EPD_RESET = { - MCP23X17_Pin(mcp2, 9), MCP23X17_Pin(mcp2, 11), MCP23X17_Pin(mcp2, 13), - MCP23X17_Pin(mcp2, 15), MCP23X17_Pin(mcp2, 1), MCP23X17_Pin(mcp2, 3), - MCP23X17_Pin(mcp2, 5), MCP23X17_Pin(mcp2, 7) -}; -#else -Native_Pin EPDManager::EPD_DC(14); -std::array EPDManager::EPD_CS = { - Native_Pin(2), Native_Pin(4), Native_Pin(6), Native_Pin(10), - Native_Pin(33), Native_Pin(21), Native_Pin(17) -}; -std::array EPDManager::EPD_BUSY = { - Native_Pin(3), Native_Pin(5), Native_Pin(7), Native_Pin(9), - Native_Pin(37), Native_Pin(18), Native_Pin(16) -}; -std::array EPDManager::EPD_RESET = { - MCP23X17_Pin(mcp1, 8), MCP23X17_Pin(mcp1, 9), MCP23X17_Pin(mcp1, 10), - MCP23X17_Pin(mcp1, 11), MCP23X17_Pin(mcp1, 12), MCP23X17_Pin(mcp1, 13), - MCP23X17_Pin(mcp1, 14) + MCP23X17_Pin(mcp2, 4), MCP23X17_Pin(mcp2, 6)}; + +MCP23X17_Pin EPD_RESET_MPD[NUM_SCREENS] = { + MCP23X17_Pin(mcp2, 9), + MCP23X17_Pin(mcp2, 11), + MCP23X17_Pin(mcp2, 13), + MCP23X17_Pin(mcp2, 15), + MCP23X17_Pin(mcp2, 1), + MCP23X17_Pin(mcp2, 3), + MCP23X17_Pin(mcp2, 5), + MCP23X17_Pin(mcp2, 7), }; + #endif -EPDManager& EPDManager::getInstance() { - static EPDManager instance; - return instance; -} +GxEPD2_BW displays[NUM_SCREENS] = { + EPD_CLASS(&EPD_CS[0], &EPD_DC, &EPD_RESET_MPD[0], &EPD_BUSY[0]), + EPD_CLASS(&EPD_CS[1], &EPD_DC, &EPD_RESET_MPD[1], &EPD_BUSY[1]), + EPD_CLASS(&EPD_CS[2], &EPD_DC, &EPD_RESET_MPD[2], &EPD_BUSY[2]), + EPD_CLASS(&EPD_CS[3], &EPD_DC, &EPD_RESET_MPD[3], &EPD_BUSY[3]), + EPD_CLASS(&EPD_CS[4], &EPD_DC, &EPD_RESET_MPD[4], &EPD_BUSY[4]), + EPD_CLASS(&EPD_CS[5], &EPD_DC, &EPD_RESET_MPD[5], &EPD_BUSY[5]), + EPD_CLASS(&EPD_CS[6], &EPD_DC, &EPD_RESET_MPD[6], &EPD_BUSY[6]), +#ifdef IS_BTCLOCK_S3 + EPD_CLASS(&EPD_CS[7], &EPD_DC, &EPD_RESET_MPD[6], &EPD_BUSY[7]), +#endif +}; -EPDManager::EPDManager() - : currentContent{} - , content{} - , lastFullRefresh{} - , tasks{} - , updateQueue{nullptr} - , antonioFonts{nullptr, nullptr, nullptr} - , oswaldFonts{nullptr, nullptr, nullptr} - , fontSmall{nullptr} - , fontBig{nullptr} - , fontMedium{nullptr} - , fontSatsymbol{nullptr} - , bgColor{GxEPD_BLACK} - , fgColor{GxEPD_WHITE} - , displays{ - #ifdef IS_BTCLOCK_V8 - EPD_CLASS(&EPD_CS[0], &EPD_DC, &EPD_RESET[0], &EPD_BUSY[0]), - EPD_CLASS(&EPD_CS[1], &EPD_DC, &EPD_RESET[1], &EPD_BUSY[1]), - EPD_CLASS(&EPD_CS[2], &EPD_DC, &EPD_RESET[2], &EPD_BUSY[2]), - EPD_CLASS(&EPD_CS[3], &EPD_DC, &EPD_RESET[3], &EPD_BUSY[3]), - EPD_CLASS(&EPD_CS[4], &EPD_DC, &EPD_RESET[4], &EPD_BUSY[4]), - EPD_CLASS(&EPD_CS[5], &EPD_DC, &EPD_RESET[5], &EPD_BUSY[5]), - EPD_CLASS(&EPD_CS[6], &EPD_DC, &EPD_RESET[6], &EPD_BUSY[6]), - EPD_CLASS(&EPD_CS[7], &EPD_DC, &EPD_RESET[7], &EPD_BUSY[7]) - #else - EPD_CLASS(&EPD_CS[0], &EPD_DC, &EPD_RESET[0], &EPD_BUSY[0]), - EPD_CLASS(&EPD_CS[1], &EPD_DC, &EPD_RESET[1], &EPD_BUSY[1]), - EPD_CLASS(&EPD_CS[2], &EPD_DC, &EPD_RESET[2], &EPD_BUSY[2]), - EPD_CLASS(&EPD_CS[3], &EPD_DC, &EPD_RESET[3], &EPD_BUSY[3]), - EPD_CLASS(&EPD_CS[4], &EPD_DC, &EPD_RESET[4], &EPD_BUSY[4]), - EPD_CLASS(&EPD_CS[5], &EPD_DC, &EPD_RESET[5], &EPD_BUSY[5]), - EPD_CLASS(&EPD_CS[6], &EPD_DC, &EPD_RESET[6], &EPD_BUSY[6]) - #endif - } +std::array currentEpdContent; +std::array epdContent; +uint32_t lastFullRefresh[NUM_SCREENS]; +TaskHandle_t tasks[NUM_SCREENS]; +// TaskHandle_t epdTaskHandle = NULL; + +#define UPDATE_QUEUE_SIZE 14 +QueueHandle_t updateQueue; + +// SemaphoreHandle_t epdUpdateSemaphore[NUM_SCREENS]; + +int fgColor = GxEPD_WHITE; +int bgColor = GxEPD_BLACK; + +#define FONT_SMALL Antonio_SemiBold20pt7b +#define FONT_BIG Antonio_SemiBold90pt7b +#define FONT_MEDIUM Antonio_SemiBold40pt7b +#define FONT_SATSYMBOL Satoshi_Symbol90pt7b +std::mutex epdUpdateMutex; +std::mutex epdMutex[NUM_SCREENS]; + +uint8_t qrcode[800]; + +void forceFullRefresh() { + for (uint i = 0; i < NUM_SCREENS; i++) + { + lastFullRefresh[i] = NULL; + } } -EPDManager::~EPDManager() { - // Clean up tasks - for (auto& task : tasks) { - if (task != nullptr) { - vTaskDelete(task); +void refreshFromMemory() +{ + for (uint i = 0; i < NUM_SCREENS; i++) + { + int *taskParam = new int; + *taskParam = i; + + xTaskCreate( + [](void *pvParameters) + { + const int epdIndex = *(int *)pvParameters; + delete (int *)pvParameters; + displays[epdIndex].refresh(false); + vTaskDelete(NULL); + }, + "PrepareUpd", 4096, taskParam, tskIDLE_PRIORITY, NULL); + } +} + +void setupDisplays() +{ + std::lock_guard lockMcp(mcpMutex); + + for (uint i = 0; i < NUM_SCREENS; i++) + { + displays[i].init(0, true, 30); + } + + updateQueue = xQueueCreate(UPDATE_QUEUE_SIZE, sizeof(UpdateDisplayTaskItem)); + + xTaskCreate(prepareDisplayUpdateTask, "PrepareUpd", 4096, NULL, 11, NULL); + + for (uint i = 0; i < NUM_SCREENS; i++) + { + // epdUpdateSemaphore[i] = xSemaphoreCreateBinary(); + // xSemaphoreGive(epdUpdateSemaphore[i]); + + int *taskParam = new int; + *taskParam = i; + + xTaskCreate(updateDisplay, ("EpdUpd" + String(i)).c_str(), 2048, taskParam, + 11, &tasks[i]); // create task + } + + // Hold lower button to enable "storage mode" (prevents burn-in of ePaper displays) + if (mcp1.digitalRead(0) == LOW) + { + setFgColor(GxEPD_BLACK); + setBgColor(GxEPD_WHITE); + + epdContent = {" ", " ", " ", " ", " ", " ", " "}; + } + else + { + + epdContent = {"B", "T", "C", "L", "O", "C", "K"}; + } + + setEpdContent(epdContent); +} + +void setEpdContent(std::array newEpdContent) +{ + setEpdContent(newEpdContent, false); +} + +void setEpdContent(std::array newEpdContent) +{ + std::array conv; + + for (size_t i = 0; i < newEpdContent.size(); ++i) + { + conv[i] = String(newEpdContent[i].c_str()); + } + + return setEpdContent(conv); +} + +void setEpdContent(std::array newEpdContent, + bool forceUpdate) +{ + std::lock_guard lock(epdUpdateMutex); + + waitUntilNoneBusy(); + + for (uint i = 0; i < NUM_SCREENS; i++) + { + if (newEpdContent[i].compareTo(currentEpdContent[i]) != 0 || forceUpdate) + { + epdContent[i] = newEpdContent[i]; + UpdateDisplayTaskItem dispUpdate = {i}; + xQueueSend(updateQueue, &dispUpdate, portMAX_DELAY); + } + } +} + +void prepareDisplayUpdateTask(void *pvParameters) +{ + UpdateDisplayTaskItem receivedItem; + + while (1) + { + // Wait for a work item to be available in the queue + if (xQueueReceive(updateQueue, &receivedItem, portMAX_DELAY)) + { + uint epdIndex = receivedItem.dispNum; + std::lock_guard lock(epdMutex[epdIndex]); + // displays[epdIndex].init(0, false); // Little longer reset duration + // because of MCP + + bool updatePartial = true; + + if (strstr(epdContent[epdIndex].c_str(), "/") != NULL) + { + String top = epdContent[epdIndex].substring( + 0, epdContent[epdIndex].indexOf("/")); + String bottom = epdContent[epdIndex].substring( + epdContent[epdIndex].indexOf("/") + 1); + splitText(epdIndex, top, bottom, updatePartial); + } + else if (epdContent[epdIndex].startsWith(F("qr"))) + { + renderQr(epdIndex, epdContent[epdIndex], updatePartial); + } + else if (epdContent[epdIndex].length() > 5) + { + renderText(epdIndex, epdContent[epdIndex], updatePartial); + } + else + { + if (epdContent[epdIndex].length() > 1 && epdContent[epdIndex].indexOf(".") == -1) + { + if (epdContent[epdIndex].equals("STS")) + { + showDigit(epdIndex, 'S', updatePartial, + &FONT_SATSYMBOL); + } + else + { + showChars(epdIndex, epdContent[epdIndex], updatePartial, + &FONT_MEDIUM); + } } - } + else + { - // Clean up queue - if (updateQueue != nullptr) { - vQueueDelete(updateQueue); - } - - // Clean up fonts - delete antonioFonts.big; - delete antonioFonts.medium; - delete antonioFonts.small; - delete oswaldFonts.big; - delete oswaldFonts.medium; - delete oswaldFonts.small; -} - -void EPDManager::initialize() { - // Load fonts based on preference - String fontName = preferences.getString("fontName", DEFAULT_FONT_NAME); - loadFonts(fontName); - - // Initialize displays - std::lock_guard lockMcp(mcpMutex); - for (auto& display : displays) { - display.init(0, true, 30); - } - - // Create update queue and task - updateQueue = xQueueCreate(UPDATE_QUEUE_SIZE, sizeof(UpdateDisplayTaskItem)); - xTaskCreate(prepareDisplayUpdateTask, "PrepareUpd", EPD_TASK_STACK_SIZE * 2, nullptr, 11, nullptr); - - // Create display update tasks - for (size_t i = 0; i < NUM_SCREENS; i++) { - auto* taskParam = new int(i); - xTaskCreate(updateDisplayTask, ("EpdUpd" + String(i)).c_str(), EPD_TASK_STACK_SIZE, - taskParam, 11, &tasks[i]); - } - - // Check for storage mode (prevents burn-in) - if (mcp1.read1(0) == LOW) { - setForegroundColor(GxEPD_BLACK); - setBackgroundColor(GxEPD_WHITE); - content.fill(""); - } else { - // Initialize with custom text or default - String customText = preferences.getString("displayText", DEFAULT_BOOT_TEXT); - std::array newContent; - newContent.fill(" "); - - for (size_t i = 0; i < std::min(customText.length(), (size_t)NUM_SCREENS); i++) { - newContent[i] = String(customText[i]); + showDigit(epdIndex, epdContent[epdIndex].c_str()[0], updatePartial, + &FONT_BIG); } - - content = newContent; + } + + xTaskNotifyGive(tasks[epdIndex]); + } + } +} + +extern "C" void updateDisplay(void *pvParameters) noexcept +{ + const int epdIndex = *(int *)pvParameters; + delete (int *)pvParameters; + + for (;;) + { + // Wait for the task notification + ulTaskNotifyTake(pdTRUE, portMAX_DELAY); + + std::lock_guard lock(epdMutex[epdIndex]); + + { + std::lock_guard lockMcp(mcpMutex); + + displays[epdIndex].init(0, false, 40); + } + uint count = 0; + while (EPD_BUSY[epdIndex].digitalRead() == HIGH || count < 10) + { + vTaskDelay(pdMS_TO_TICKS(100)); + count++; } - setContent(content); -} + bool updatePartial = true; -void EPDManager::loadFonts(const String& fontName) { - if (fontName == FontNames::ANTONIO) { - // Load Antonio fonts - antonioFonts.big = FontLoader::loadCompressedFont(Antonio_SemiBold90pt7b_Properties); - antonioFonts.medium = FontLoader::loadCompressedFont(Antonio_SemiBold40pt7b_Properties); - antonioFonts.small = FontLoader::loadCompressedFont(Antonio_SemiBold20pt7b_Properties); - - fontBig = antonioFonts.big; - fontMedium = antonioFonts.medium; - fontSmall = antonioFonts.small; - } else if (fontName == FontNames::OSWALD) { - // Load Oswald fonts - oswaldFonts.big = FontLoader::loadCompressedFont(Oswald_Medium80pt7b_Properties); - oswaldFonts.medium = FontLoader::loadCompressedFont(Oswald_Medium30pt7b_Properties); - oswaldFonts.small = FontLoader::loadCompressedFont(Oswald_Medium20pt7b_Properties); - - fontBig = oswaldFonts.big; - fontMedium = oswaldFonts.medium; - fontSmall = oswaldFonts.small; + // Full Refresh every x minutes + if (!lastFullRefresh[epdIndex] || + (millis() - lastFullRefresh[epdIndex]) > + (preferences.getUInt("fullRefreshMin", + DEFAULT_MINUTES_FULL_REFRESH) * + 60 * 1000)) + { + updatePartial = false; } - fontSatsymbol = FontLoader::loadCompressedFont(Satoshi_Symbol90pt7b_Properties); -} + char tries = 0; + while (tries < 3) + { + if (displays[epdIndex].displayWithReturn(updatePartial)) + { + displays[epdIndex].powerOff(); + currentEpdContent[epdIndex] = epdContent[epdIndex]; + if (!updatePartial) + lastFullRefresh[epdIndex] = millis(); -void EPDManager::forceFullRefresh() { - std::fill(lastFullRefresh.begin(), lastFullRefresh.end(), 0); -} + if (eventSourceTaskHandle != NULL) + xTaskNotifyGive(eventSourceTaskHandle); -void EPDManager::setContent(const std::array& newContent, bool forceUpdate) { - std::lock_guard lock(updateMutex); - waitUntilNoneBusy(); + break; + } - for (size_t i = 0; i < NUM_SCREENS; i++) { - if (newContent[i].compareTo(currentContent[i]) != 0 || forceUpdate) { - content[i] = newContent[i]; - UpdateDisplayTaskItem dispUpdate{static_cast(i)}; - xQueueSend(updateQueue, &dispUpdate, portMAX_DELAY); - } + vTaskDelay(pdMS_TO_TICKS(100)); + tries++; } + } } -void EPDManager::setContent(const std::array& newContent) { - std::array conv; - for (size_t i = 0; i < newContent.size(); ++i) { - conv[i] = String(newContent[i].c_str()); +void splitText(const uint dispNum, const String &top, const String &bottom, + bool partial) +{ + displays[dispNum].setRotation(2); + displays[dispNum].setFont(&FONT_SMALL); + displays[dispNum].setTextColor(getFgColor()); + + // Top text + int16_t ttbx, ttby; + uint16_t ttbw, ttbh; + displays[dispNum].getTextBounds(top, 0, 0, &ttbx, &ttby, &ttbw, &ttbh); + uint16_t tx = ((displays[dispNum].width() - ttbw) / 2) - ttbx; + uint16_t ty = + ((displays[dispNum].height() - ttbh) / 2) - ttby - ttbh / 2 - 12; + + // Bottom text + int16_t tbbx, tbby; + uint16_t tbbw, tbbh; + displays[dispNum].getTextBounds(bottom, 0, 0, &tbbx, &tbby, &tbbw, &tbbh); + uint16_t bx = ((displays[dispNum].width() - tbbw) / 2) - tbbx; + uint16_t by = + ((displays[dispNum].height() - tbbh) / 2) - tbby + tbbh / 2 + 12; + + // Make separator as wide as the shortest text. + uint16_t lineWidth, lineX; + if (tbbw < ttbh) + lineWidth = tbbw; + else + lineWidth = ttbw; + lineX = round((displays[dispNum].width() - lineWidth) / 2); + + displays[dispNum].fillScreen(getBgColor()); + displays[dispNum].setCursor(tx, ty); + displays[dispNum].print(top); + displays[dispNum].fillRoundRect(lineX, displays[dispNum].height() / 2 - 3, + lineWidth, 6, 3, getFgColor()); + displays[dispNum].setCursor(bx, by); + displays[dispNum].print(bottom); +} + +void showDigit(const uint dispNum, char chr, bool partial, + const GFXfont *font) +{ + String str(chr); + + if (chr == '.') + { + str = "!"; + } + displays[dispNum].setRotation(2); + displays[dispNum].setFont(font); + displays[dispNum].setTextColor(getFgColor()); + int16_t tbx, tby; + uint16_t tbw, tbh; + + displays[dispNum].getTextBounds(str, 0, 0, &tbx, &tby, &tbw, &tbh); + + // center the bounding box by transposition of the origin: + uint16_t x = ((displays[dispNum].width() - tbw) / 2) - tbx; + uint16_t y = ((displays[dispNum].height() - tbh) / 2) - tby; + + // if (str.equals(".")) + // { + // // int16_t yAdvance = font->yAdvance; + // // uint8_t charIndex = 46 - font->first; + // // GFXglyph *glyph = (&font->glyph)[charIndex]; + // int16_t tbx2, tby2; + // uint16_t tbw2, tbh2; + // displays[dispNum].getTextBounds(".!", 0, 0, &tbx2, &tby2, &tbw2, &tbh2); + + // y = ((displays[dispNum].height() - tbh2) / 2) - tby2; + // // Serial.print("yAdvance"); + // // Serial.println(yAdvance); + // // if (glyph != nullptr) { + // // Serial.print("height"); + // // Serial.println(glyph->height); + // // Serial.print("yOffset"); + // // Serial.println(glyph->yOffset); + // // } + + // // y = 250-99+18+19; + // } + + displays[dispNum].fillScreen(getBgColor()); + + displays[dispNum].setCursor(x, y); + displays[dispNum].print(str); + + if (chr == '.') + { + displays[dispNum].fillRect(x, y, displays[dispNum].width(), round(displays[dispNum].height() * 0.9), getBgColor()); + } + + // displays[dispNum].setCursor(10, 3); + // displays[dispNum].setFont(&FONT_SMALL); + // displays[dispNum].setTextColor(getFgColor()); + // displays[dispNum].println("Y = " + y); +} + +void showChars(const uint dispNum, const String &chars, bool partial, + const GFXfont *font) +{ + displays[dispNum].setRotation(2); + displays[dispNum].setFont(font); + displays[dispNum].setTextColor(getFgColor()); + int16_t tbx, tby; + uint16_t tbw, tbh; + displays[dispNum].getTextBounds(chars, 0, 0, &tbx, &tby, &tbw, &tbh); + // center the bounding box by transposition of the origin: + uint16_t x = ((displays[dispNum].width() - tbw) / 2) - tbx; + uint16_t y = ((displays[dispNum].height() - tbh) / 2) - tby; + displays[dispNum].fillScreen(getBgColor()); + displays[dispNum].setCursor(x, y); + displays[dispNum].print(chars); +} + +int getBgColor() { return bgColor; } + +int getFgColor() { return fgColor; } + +void setBgColor(int color) { bgColor = color; } + +void setFgColor(int color) { fgColor = color; } + +std::array getCurrentEpdContent() +{ + return currentEpdContent; +} +void renderText(const uint dispNum, const String &text, bool partial) +{ + displays[dispNum].setRotation(2); + displays[dispNum].setPartialWindow(0, 0, displays[dispNum].width(), + displays[dispNum].height()); + displays[dispNum].fillScreen(GxEPD_WHITE); + displays[dispNum].setTextColor(GxEPD_BLACK); + displays[dispNum].setCursor(0, 50); + + std::stringstream ss; + ss.str(text.c_str()); + + std::string line; + + while (std::getline(ss, line, '\n')) + { + if (line.rfind("*", 0) == 0) + { + line.erase(std::remove(line.begin(), line.end(), '*'), line.end()); + + displays[dispNum].setFont(&FreeSansBold9pt7b); + displays[dispNum].println(line.c_str()); } - setContent(conv); -} - -std::array EPDManager::getCurrentContent() const { - return currentContent; -} - -void EPDManager::waitUntilNoneBusy() { - for (size_t i = 0; i < NUM_SCREENS; i++) { - uint32_t count = 0; - while (EPD_BUSY[i].digitalRead()) { - count++; - vTaskDelay(BUSY_RETRY_DELAY); - - if (count == BUSY_TIMEOUT_COUNT) { - vTaskDelay(pdMS_TO_TICKS(100)); - } else if (count > BUSY_TIMEOUT_COUNT + 5) { - log_e("Display %d busy timeout", i); - break; - } - } + else + { + displays[dispNum].setFont(&FreeSans9pt7b); + displays[dispNum].println(line.c_str()); } + } } -void EPDManager::setupDisplay(uint dispNum, const GFXfont* font) { - displays[dispNum].setRotation(2); - displays[dispNum].setFont(font); - displays[dispNum].setTextColor(fgColor); - displays[dispNum].fillScreen(bgColor); -} - -void EPDManager::splitText(uint dispNum, const String& top, const String& bottom, bool partial) { - if (preferences.getBool("verticalDesc", DEFAULT_VERTICAL_DESC) && dispNum == 0) { - displays[dispNum].setRotation(1); - } else { - displays[dispNum].setRotation(2); - } - displays[dispNum].setFont(fontSmall); - displays[dispNum].setTextColor(fgColor); - - // Top text - int16_t ttbx, ttby; - uint16_t ttbw, ttbh; - displays[dispNum].getTextBounds(top, 0, 0, &ttbx, &ttby, &ttbw, &ttbh); - uint16_t tx = ((displays[dispNum].width() - ttbw) / 2) - ttbx; - uint16_t ty = ((displays[dispNum].height() - ttbh) / 2) - ttby - ttbh / 2 - 12; - - // Bottom text - int16_t tbbx, tbby; - uint16_t tbbw, tbbh; - displays[dispNum].getTextBounds(bottom, 0, 0, &tbbx, &tbby, &tbbw, &tbbh); - uint16_t bx = ((displays[dispNum].width() - tbbw) / 2) - tbbx; - uint16_t by = ((displays[dispNum].height() - tbbh) / 2) - tbby + tbbh / 2 + 12; - - // Make separator as wide as the shortest text - uint16_t lineWidth = (tbbw < ttbh) ? tbbw : ttbw; - uint16_t lineX = round((displays[dispNum].width() - lineWidth) / 2); - - displays[dispNum].fillScreen(bgColor); - displays[dispNum].setCursor(tx, ty); - displays[dispNum].print(top); - displays[dispNum].fillRoundRect(lineX, displays[dispNum].height() / 2 - 3, - lineWidth, 6, 3, fgColor); - displays[dispNum].setCursor(bx, by); - displays[dispNum].print(bottom); -} - -void EPDManager::showDigit(uint dispNum, char chr, bool partial, const GFXfont* font) { - String str(chr); - if (chr == '.') { - str = "!"; - } - - setupDisplay(dispNum, font); - - int16_t tbx, tby; - uint16_t tbw, tbh; - displays[dispNum].getTextBounds(str, 0, 0, &tbx, &tby, &tbw, &tbh); - - uint16_t x = ((displays[dispNum].width() - tbw) / 2) - tbx; - uint16_t y = ((displays[dispNum].height() - tbh) / 2) - tby; - - displays[dispNum].setCursor(x, y); - displays[dispNum].print(str); - - if (chr == '.') { - displays[dispNum].fillRect(0, 0, displays[dispNum].width(), - round(displays[dispNum].height() * 0.67), bgColor); - } -} - -void EPDManager::showChars(uint dispNum, const String& chars, bool partial, const GFXfont* font) { - setupDisplay(dispNum, font); - - int16_t tbx, tby; - uint16_t tbw, tbh; - displays[dispNum].getTextBounds(chars, 0, 0, &tbx, &tby, &tbw, &tbh); - - // Center the bounding box by transposition of the origin - uint16_t x = ((displays[dispNum].width() - tbw) / 2) - tbx; - uint16_t y = ((displays[dispNum].height() - tbh) / 2) - tby; - - for (size_t i = 0; i < chars.length(); i++) { - char c = chars[i]; - if (c == '.' || c == ',') { - // For the dot, calculate its specific descent - GFXglyph* dotGlyph = &font->glyph[c - font->first]; - int16_t dotDescent = dotGlyph->yOffset; - - // Draw the dot with adjusted y-position - displays[dispNum].setCursor(x, y + dotDescent + dotGlyph->height + 8); - displays[dispNum].print(c); - } else { - // For other characters, use the original y-position - displays[dispNum].setCursor(x, y); - displays[dispNum].print(c); - } - - // Move x-position for the next character - x += font->glyph[c - font->first].xAdvance; - } -} - -bool EPDManager::renderIcon(uint dispNum, const String& text, bool partial) { - displays[dispNum].setRotation(2); - displays[dispNum].setPartialWindow(0, 0, displays[dispNum].width(), - displays[dispNum].height()); - displays[dispNum].fillScreen(bgColor); - displays[dispNum].setTextColor(fgColor); - - uint iconIndex = 0; - uint width = 122; - uint height = 122; - - if (text.endsWith("rocket")) { - iconIndex = 1; - } else if (text.endsWith("lnbolt")) { - iconIndex = 2; - } else if (text.endsWith("bitaxe")) { - width = 88; - height = 220; - iconIndex = 3; - } else if (text.endsWith("miningpool")) { - LogoData logo = MiningPoolStatsFetch::getInstance().getLogo(); - if (logo.size == 0) { - Serial.println(F("No logo found")); - return false; - } - - int x_offset = (displays[dispNum].width() - logo.width) / 2; - int y_offset = (displays[dispNum].height() - logo.height) / 2; - displays[dispNum].drawInvertedBitmap(x_offset, y_offset, logo.data, - logo.width, logo.height, fgColor); - return true; - } - - int x_offset = (displays[dispNum].width() - width) / 2; - int y_offset = (displays[dispNum].height() - height) / 2; - displays[dispNum].drawInvertedBitmap(x_offset, y_offset, epd_icons_allArray[iconIndex], - width, height, fgColor); - return true; -} - -void EPDManager::renderText(uint dispNum, const String& text, bool partial) { - displays[dispNum].setRotation(2); - displays[dispNum].setPartialWindow(0, 0, displays[dispNum].width(), - displays[dispNum].height()); - displays[dispNum].fillScreen(GxEPD_WHITE); - displays[dispNum].setTextColor(GxEPD_BLACK); - displays[dispNum].setCursor(0, 50); - - std::stringstream ss; - ss.str(text.c_str()); - std::string line; - - while (std::getline(ss, line, '\n')) { - if (line.rfind("*", 0) == 0) { - line.erase(std::remove(line.begin(), line.end(), '*'), line.end()); - displays[dispNum].setFont(&FreeSansBold9pt7b); - } else { - displays[dispNum].setFont(&FreeSans9pt7b); - } - displays[dispNum].println(line.c_str()); - } -} - -void EPDManager::renderQr(uint dispNum, const String& text, bool partial) { +void renderQr(const uint dispNum, const String &text, bool partial) +{ #ifdef USE_QR - // Dynamically allocate QR buffer - uint8_t* qrcode = (uint8_t*)malloc(qrcodegen_BUFFER_LEN_MAX); - if (!qrcode) { - log_e("Failed to allocate QR buffer"); - return; + + uint8_t tempBuffer[800]; + bool ok = qrcodegen_encodeText( + text.substring(2).c_str(), tempBuffer, qrcode, qrcodegen_Ecc_LOW, + qrcodegen_VERSION_MIN, qrcodegen_VERSION_MAX, qrcodegen_Mask_AUTO, true); + + const int size = qrcodegen_getSize(qrcode); + + const int padding = floor(float(displays[dispNum].width() - (size * 4)) / 2); + const int paddingY = + floor(float(displays[dispNum].height() - (size * 4)) / 2); + displays[dispNum].setRotation(2); + + displays[dispNum].setPartialWindow(0, 0, displays[dispNum].width(), + displays[dispNum].height()); + displays[dispNum].fillScreen(GxEPD_WHITE); + const int border = 0; + + for (int y = -border; y < size * 4 + border; y++) + { + for (int x = -border; x < size * 4 + border; x++) + { + displays[dispNum].drawPixel( + padding + x, paddingY + y, + qrcodegen_getModule(qrcode, floor(float(x) / 4), floor(float(y) / 4)) + ? GxEPD_BLACK + : GxEPD_WHITE); } - - uint8_t tempBuffer[800]; - bool ok = qrcodegen_encodeText( - text.substring(2).c_str(), tempBuffer, qrcode, qrcodegen_Ecc_LOW, - qrcodegen_VERSION_MIN, qrcodegen_VERSION_MAX, qrcodegen_Mask_AUTO, true); - - if (ok) { - const int size = qrcodegen_getSize(qrcode); - const int padding = floor(float(displays[dispNum].width() - (size * 4)) / 2); - const int paddingY = floor(float(displays[dispNum].height() - (size * 4)) / 2); - - displays[dispNum].setRotation(2); - displays[dispNum].setPartialWindow(0, 0, displays[dispNum].width(), - displays[dispNum].height()); - displays[dispNum].fillScreen(GxEPD_WHITE); - - for (int y = 0; y < size * 4; y++) { - for (int x = 0; x < size * 4; x++) { - displays[dispNum].drawPixel( - padding + x, paddingY + y, - qrcodegen_getModule(qrcode, floor(float(x) / 4), floor(float(y) / 4)) - ? GxEPD_BLACK - : GxEPD_WHITE); - } - } - } - - free(qrcode); + } #endif } -int16_t EPDManager::calculateDescent(const GFXfont* font) { - int16_t maxDescent = 0; - for (uint16_t i = font->first; i <= font->last; i++) { - GFXglyph* glyph = &font->glyph[i - font->first]; - int16_t descent = glyph->yOffset; - if (descent > maxDescent) { - maxDescent = descent; - } - } - return maxDescent; -} - -void EPDManager::updateDisplayTask(void* pvParameters) noexcept { - auto& instance = EPDManager::getInstance(); - const int epdIndex = *(int*)pvParameters; - delete (int*)pvParameters; - - for (;;) { - ulTaskNotifyTake(pdTRUE, portMAX_DELAY); - - std::lock_guard lock(instance.displayMutexes[epdIndex]); - { - std::lock_guard lockMcp(mcpMutex); - instance.displays[epdIndex].init(0, false, 40); - } - - uint32_t count = 0; - while (instance.EPD_BUSY[epdIndex].digitalRead() == HIGH || count < 10) { - vTaskDelay(pdMS_TO_TICKS(100)); - count++; - } - - bool updatePartial = true; - if (!instance.lastFullRefresh[epdIndex] || - (millis() - instance.lastFullRefresh[epdIndex]) > - (preferences.getUInt("fullRefreshMin", DEFAULT_MINUTES_FULL_REFRESH) * 60 * 1000)) { - updatePartial = false; - } - - char tries = 0; - while (tries < 3) { - if (instance.displays[epdIndex].displayWithReturn(updatePartial)) { - instance.displays[epdIndex].powerOff(); - instance.currentContent[epdIndex] = instance.content[epdIndex]; - if (!updatePartial) { - instance.lastFullRefresh[epdIndex] = millis(); - } - - if (eventSourceTaskHandle != nullptr) { - xTaskNotifyGive(eventSourceTaskHandle); - } - break; - } - - vTaskDelay(pdMS_TO_TICKS(100)); - tries++; - } - } -} - -void EPDManager::prepareDisplayUpdateTask(void* pvParameters) { - auto& instance = EPDManager::getInstance(); - UpdateDisplayTaskItem receivedItem; - - for (;;) { - if (xQueueReceive(instance.updateQueue, &receivedItem, portMAX_DELAY)) { - uint epdIndex = receivedItem.dispNum; - std::lock_guard lock(instance.displayMutexes[epdIndex]); - - bool updatePartial = true; - - if (instance.content[epdIndex].length() > 1 && - strstr(instance.content[epdIndex].c_str(), "/") != nullptr) { - String top = instance.content[epdIndex].substring( - 0, instance.content[epdIndex].indexOf("/")); - String bottom = instance.content[epdIndex].substring( - instance.content[epdIndex].indexOf("/") + 1); - instance.splitText(epdIndex, top, bottom, updatePartial); - } else if (instance.content[epdIndex].startsWith(F("qr"))) { - instance.renderQr(epdIndex, instance.content[epdIndex], updatePartial); - } else if (instance.content[epdIndex].startsWith(F("mdi"))) { - if (!instance.renderIcon(epdIndex, instance.content[epdIndex], updatePartial)) { - continue; - } - } else if (instance.content[epdIndex].length() > 5) { - instance.renderText(epdIndex, instance.content[epdIndex], updatePartial); - } else { - if (instance.content[epdIndex].length() == 2) { - instance.showChars(epdIndex, instance.content[epdIndex], updatePartial, instance.fontBig); - } else if (instance.content[epdIndex].length() > 1 && - instance.content[epdIndex].indexOf(".") == -1) { - if (instance.content[epdIndex].equals("STS")) { - instance.showDigit(epdIndex, 'S', updatePartial, instance.fontSatsymbol); - } else { - instance.showChars(epdIndex, instance.content[epdIndex], updatePartial, - instance.fontMedium); - } - } else { - instance.showDigit(epdIndex, instance.content[epdIndex].c_str()[0], - updatePartial, instance.fontBig); - } - } - - xTaskNotifyGive(instance.tasks[epdIndex]); - } +void waitUntilNoneBusy() +{ + for (int i = 0; i < NUM_SCREENS; i++) + { + uint count = 0; + while (EPD_BUSY[i].digitalRead()) + { + count++; + vTaskDelay(10); + if (count == 200) + { + // displays[i].init(0, false); + vTaskDelay(100); + } + else if (count > 205) + { + Serial.printf("Busy timeout %d", i); + break; + } } + } } \ No newline at end of file diff --git a/src/lib/epd.hpp b/src/lib/epd.hpp index 80bed83..275aaae 100644 --- a/src/lib/epd.hpp +++ b/src/lib/epd.hpp @@ -3,133 +3,53 @@ #include #include #include -#include "gzip_decompressor.hpp" #include #include #include #include -#include -#include #include "fonts/fonts.hpp" #include "lib/config.hpp" #include "lib/shared.hpp" -#include "icons/icons.h" -#include "mining_pool_stats_fetch.hpp" - -// Font includes -#include "../fonts/antonio-semibold20.h" -#include "../fonts/antonio-semibold40.h" -#include "../fonts/antonio-semibold90.h" - -// Oswald fonts -#include "../fonts/oswald-medium20.h" -#include "../fonts/oswald-medium30.h" -#include "../fonts/oswald-medium80.h" - -#include "../fonts/sats-symbol.h" #ifdef USE_QR #include "qrcodegen.h" #endif +// extern TaskHandle_t epdTaskHandle; -struct UpdateDisplayTaskItem { - char dispNum; -}; +typedef struct { + char dispNum; +} UpdateDisplayTaskItem; -struct FontFamily { - GFXfont* big; - GFXfont* medium; - GFXfont* small; -}; +void forceFullRefresh(); +void refreshFromMemory(); +void setupDisplays(); -class EPDManager { -public: - static EPDManager& getInstance(); +void splitText(const uint dispNum, const String &top, const String &bottom, + bool partial); - // Delete copy constructor and assignment operator - EPDManager(const EPDManager&) = delete; - EPDManager& operator=(const EPDManager&) = delete; +void showDigit(const uint dispNum, char chr, bool partial, const GFXfont *font); +void showChars(const uint dispNum, const String &chars, bool partial, + const GFXfont *font); - void initialize(); - void forceFullRefresh(); - void loadFonts(const String& fontName); - void setContent(const std::array& newContent, bool forceUpdate = false); - void setContent(const std::array& newContent); - std::array getCurrentContent() const; +extern "C" void updateDisplay(void *pvParameters) noexcept; +void updateDisplayAlt(int epdIndex); +void prepareDisplayUpdateTask(void *pvParameters); - int getBackgroundColor() const { return bgColor; } - int getForegroundColor() const { return fgColor; } - void setBackgroundColor(int color) { bgColor = color; } - void setForegroundColor(int color) { fgColor = color; } - void waitUntilNoneBusy(); +int getBgColor(); +int getFgColor(); +void setBgColor(int color); +void setFgColor(int color); -private: - EPDManager(); // Private constructor for singleton - ~EPDManager(); // Private destructor +void renderText(const uint dispNum, const String &text, bool partial); +void renderQr(const uint dispNum, const String &text, bool partial); - void setupDisplay(uint dispNum, const GFXfont* font); - void splitText(uint dispNum, const String& top, const String& bottom, bool partial); - void showDigit(uint dispNum, char chr, bool partial, const GFXfont* font); - void showChars(uint dispNum, const String& chars, bool partial, const GFXfont* font); - bool renderIcon(uint dispNum, const String& text, bool partial); - void renderText(uint dispNum, const String& text, bool partial); - void renderQr(uint dispNum, const String& text, bool partial); - int16_t calculateDescent(const GFXfont* font); +void setEpdContent(std::array newEpdContent, + bool forceUpdate); +void setEpdContent(std::array newEpdContent); - static void updateDisplayTask(void* pvParameters) noexcept; - static void prepareDisplayUpdateTask(void* pvParameters); +void setEpdContent(std::array newEpdContent); - // Member variables - std::array currentContent; - std::array content; - std::array lastFullRefresh; - std::array tasks; - QueueHandle_t updateQueue; - - FontFamily antonioFonts; - FontFamily oswaldFonts; - const GFXfont* fontSmall; - const GFXfont* fontBig; - const GFXfont* fontMedium; - const GFXfont* fontSatsymbol; - - int bgColor; - int fgColor; - - std::mutex updateMutex; - std::array displayMutexes; - - // Pin configurations based on board version - #ifdef IS_BTCLOCK_REV_B - static Native_Pin EPD_DC; - static std::array EPD_CS; - static std::array EPD_BUSY; - static std::array EPD_RESET; - #elif defined(IS_BTCLOCK_V8) - static Native_Pin EPD_DC; - static std::array EPD_BUSY; - static std::array EPD_CS; - static std::array EPD_RESET; - #else - static Native_Pin EPD_DC; - static std::array EPD_CS; - static std::array EPD_BUSY; - static std::array EPD_RESET; - #endif - - // Display array - std::array, NUM_SCREENS> displays; - - static constexpr size_t UPDATE_QUEUE_SIZE = 14; - static constexpr uint32_t BUSY_TIMEOUT_COUNT = 200; - static constexpr TickType_t BUSY_RETRY_DELAY = pdMS_TO_TICKS(10); - static constexpr size_t EPD_TASK_STACK_SIZE = - #ifdef IS_BTCLOCK_V8 - 4096 - #else - 2048 - #endif - ; -}; \ No newline at end of file +std::array getCurrentEpdContent(); +void waitUntilNoneBusy(); \ No newline at end of file diff --git a/src/lib/gzip_decompressor.hpp b/src/lib/gzip_decompressor.hpp deleted file mode 100644 index a74b04e..0000000 --- a/src/lib/gzip_decompressor.hpp +++ /dev/null @@ -1,49 +0,0 @@ -#pragma once - -#include "rom/miniz.h" -#include - -class GzipDecompressor { -public: - static bool decompressData(const uint8_t* input, size_t inputSize, - uint8_t* output, size_t* outputSize) { - if (!input || !output || !outputSize || inputSize < 18) { // Minimum gzip size - return false; - } - - tinfl_decompressor* decomp = new tinfl_decompressor; - if (!decomp) { - return false; - } - - tinfl_init(decomp); - - size_t inPos = 10; // Skip gzip header - size_t outPos = 0; - - while (inPos < inputSize - 8) { // -8 for footer - size_t inBytes = inputSize - inPos - 8; - size_t outBytes = *outputSize - outPos; - - tinfl_status status = tinfl_decompress(decomp, - &input[inPos], &inBytes, - output, &output[outPos], &outBytes, - TINFL_FLAG_HAS_MORE_INPUT | TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF); - - inPos += inBytes; - outPos += outBytes; - - if (status == TINFL_STATUS_DONE) { - *outputSize = outPos; - delete decomp; - return true; - } else if (status < 0) { - delete decomp; - return false; - } - } - - delete decomp; - return false; - } -}; \ No newline at end of file diff --git a/src/lib/improv.cpp b/src/lib/improv.cpp new file mode 100644 index 0000000..3de3ef5 --- /dev/null +++ b/src/lib/improv.cpp @@ -0,0 +1,143 @@ +#include "improv.h" + +namespace improv { + +ImprovCommand parse_improv_data(const std::vector &data, + bool check_checksum) { + return parse_improv_data(data.data(), data.size(), check_checksum); +} + +ImprovCommand parse_improv_data(const uint8_t *data, size_t length, + bool check_checksum) { + ImprovCommand improv_command; + Command command = (Command)data[0]; + uint8_t data_length = data[1]; + + if (data_length != length - 2 - check_checksum) { + improv_command.command = UNKNOWN; + return improv_command; + } + + if (check_checksum) { + uint8_t checksum = data[length - 1]; + + uint32_t calculated_checksum = 0; + for (uint8_t i = 0; i < length - 1; i++) { + calculated_checksum += data[i]; + } + + if ((uint8_t)calculated_checksum != checksum) { + improv_command.command = BAD_CHECKSUM; + return improv_command; + } + } + + if (command == WIFI_SETTINGS) { + uint8_t ssid_length = data[2]; + uint8_t ssid_start = 3; + size_t ssid_end = ssid_start + ssid_length; + + uint8_t pass_length = data[ssid_end]; + size_t pass_start = ssid_end + 1; + size_t pass_end = pass_start + pass_length; + + std::string ssid(data + ssid_start, data + ssid_end); + std::string password(data + pass_start, data + pass_end); + return {.command = command, .ssid = ssid, .password = password}; + } + + improv_command.command = command; + return improv_command; +} + +bool parse_improv_serial_byte(size_t position, uint8_t byte, + const uint8_t *buffer, + std::function &&callback, + std::function &&on_error) { + if (position == 0) return byte == 'I'; + if (position == 1) return byte == 'M'; + if (position == 2) return byte == 'P'; + if (position == 3) return byte == 'R'; + if (position == 4) return byte == 'O'; + if (position == 5) return byte == 'V'; + + if (position == 6) return byte == IMPROV_SERIAL_VERSION; + + if (position <= 8) return true; + + uint8_t type = buffer[7]; + uint8_t data_len = buffer[8]; + + if (position <= 8 + data_len) return true; + + if (position == 8 + data_len + 1) { + uint8_t checksum = 0x00; + for (size_t i = 0; i < position; i++) checksum += buffer[i]; + + if (checksum != byte) { + on_error(ERROR_INVALID_RPC); + return false; + } + + if (type == TYPE_RPC) { + auto command = parse_improv_data(&buffer[9], data_len, false); + return callback(command); + } + } + + return false; +} + +std::vector build_rpc_response(Command command, + const std::vector &datum, + bool add_checksum) { + std::vector out; + uint32_t length = 0; + out.push_back(command); + for (const auto &str : datum) { + uint8_t len = str.length(); + length += len + 1; + out.push_back(len); + out.insert(out.end(), str.begin(), str.end()); + } + out.insert(out.begin() + 1, length); + + if (add_checksum) { + uint32_t calculated_checksum = 0; + + for (uint8_t byte : out) { + calculated_checksum += byte; + } + out.push_back(calculated_checksum); + } + return out; +} + +#ifdef ARDUINO +std::vector build_rpc_response(Command command, + const std::vector &datum, + bool add_checksum) { + std::vector out; + uint32_t length = 0; + out.push_back(command); + for (const auto &str : datum) { + uint8_t len = str.length(); + length += len; + out.push_back(len); + out.insert(out.end(), str.begin(), str.end()); + } + out.insert(out.begin() + 1, length); + + if (add_checksum) { + uint32_t calculated_checksum = 0; + + for (uint8_t byte : out) { + calculated_checksum += byte; + } + out.push_back(calculated_checksum); + } + return out; +} +#endif // ARDUINO + +} // namespace improv \ No newline at end of file diff --git a/src/lib/improv.hpp b/src/lib/improv.hpp new file mode 100644 index 0000000..1c9453d --- /dev/null +++ b/src/lib/improv.hpp @@ -0,0 +1,86 @@ +#pragma once + +#ifdef ARDUINO +#include +#endif // ARDUINO + +#include +#include +#include +#include + +namespace improv { + +static const char *const SERVICE_UUID = "00467768-6228-2272-4663-277478268000"; +static const char *const STATUS_UUID = "00467768-6228-2272-4663-277478268001"; +static const char *const ERROR_UUID = "00467768-6228-2272-4663-277478268002"; +static const char *const RPC_COMMAND_UUID = + "00467768-6228-2272-4663-277478268003"; +static const char *const RPC_RESULT_UUID = + "00467768-6228-2272-4663-277478268004"; +static const char *const CAPABILITIES_UUID = + "00467768-6228-2272-4663-277478268005"; + +enum Error : uint8_t { + ERROR_NONE = 0x00, + ERROR_INVALID_RPC = 0x01, + ERROR_UNKNOWN_RPC = 0x02, + ERROR_UNABLE_TO_CONNECT = 0x03, + ERROR_NOT_AUTHORIZED = 0x04, + ERROR_UNKNOWN = 0xFF, +}; + +enum State : uint8_t { + STATE_STOPPED = 0x00, + STATE_AWAITING_AUTHORIZATION = 0x01, + STATE_AUTHORIZED = 0x02, + STATE_PROVISIONING = 0x03, + STATE_PROVISIONED = 0x04, +}; + +enum Command : uint8_t { + UNKNOWN = 0x00, + WIFI_SETTINGS = 0x01, + IDENTIFY = 0x02, + GET_CURRENT_STATE = 0x02, + GET_DEVICE_INFO = 0x03, + GET_WIFI_NETWORKS = 0x04, + BAD_CHECKSUM = 0xFF, +}; + +static const uint8_t CAPABILITY_IDENTIFY = 0x01; +static const uint8_t IMPROV_SERIAL_VERSION = 1; + +enum ImprovSerialType : uint8_t { + TYPE_CURRENT_STATE = 0x01, + TYPE_ERROR_STATE = 0x02, + TYPE_RPC = 0x03, + TYPE_RPC_RESPONSE = 0x04 +}; + +struct ImprovCommand { + Command command; + std::string ssid; + std::string password; +}; + +ImprovCommand parse_improv_data(const std::vector &data, + bool check_checksum = true); +ImprovCommand parse_improv_data(const uint8_t *data, size_t length, + bool check_checksum = true); + +bool parse_improv_serial_byte(size_t position, uint8_t byte, + const uint8_t *buffer, + std::function &&callback, + std::function &&on_error); + +std::vector build_rpc_response(Command command, + const std::vector &datum, + bool add_checksum = true); +#ifdef ARDUINO +std::vector build_rpc_response(Command command, + const std::vector &datum, + bool add_checksum = true); +#endif // ARDUINO + +} // namespace improv \ No newline at end of file diff --git a/src/lib/led_handler.cpp b/src/lib/led_handler.cpp index 453b067..a809e75 100644 --- a/src/lib/led_handler.cpp +++ b/src/lib/led_handler.cpp @@ -1,670 +1,332 @@ #include "led_handler.hpp" -// Singleton instance -LedHandler& LedHandler::getInstance() { - static LedHandler instance; - return instance; -} +TaskHandle_t ledTaskHandle = NULL; +QueueHandle_t ledTaskQueue = NULL; +Adafruit_NeoPixel pixels(NEOPIXEL_COUNT, NEOPIXEL_PIN, NEO_GRB + NEO_KHZ800); +uint ledTaskParams; -LedHandler::LedHandler() - : pixels(NEOPIXEL_COUNT, NEOPIXEL_PIN, NEO_GRB + NEO_KHZ800) - , ledTaskHandle(nullptr) - , ledTaskQueue(nullptr) - , ledTaskParams(0) - , dndEnabled(false) - , dndTimeBasedEnabled(false) - , dndTimeRange{23, 0, 7, 0} // Default: 23:00 to 07:00 -#ifdef HAS_FRONTLIGHT - , frontlightOn(false) - , flInTransition(false) -#endif -{ -} +void ledTask(void *parameter) { + while (1) { + if (ledTaskQueue != NULL) { + if (xQueueReceive(ledTaskQueue, &ledTaskParams, portMAX_DELAY) == + pdPASS) { -void LedHandler::setup() { - loadDNDSettings(); - pixels.begin(); - pixels.setBrightness(preferences.getUInt("ledBrightness", DEFAULT_LED_BRIGHTNESS)); - pixels.clear(); - pixels.show(); - setupTask(); - - if (preferences.getBool("ledTestOnPower", DEFAULT_LED_TEST_ON_POWER)) { - while (!ledTaskQueue) { - delay(1); + if (preferences.getBool("disableLeds", false)) { + continue; } - queueEffect(LED_POWER_TEST); - } -} -void LedHandler::setupTask() { - ledTaskQueue = xQueueCreate(5, sizeof(uint)); - xTaskCreate(ledTask, "LedTask", 2048, this, 10, &ledTaskHandle); -} + uint32_t oldLights[NEOPIXEL_COUNT]; -void LedHandler::ledTask(void* pvParameters) { - auto* handler = static_cast(pvParameters); - while (true) { - if (handler->ledTaskQueue != nullptr) { - if (xQueueReceive(handler->ledTaskQueue, &handler->ledTaskParams, portMAX_DELAY) == pdPASS) { - if (preferences.getBool("disableLeds", DEFAULT_DISABLE_LEDS)) { - continue; + // get current state + for (int i = 0; i < NEOPIXEL_COUNT; i++) { + oldLights[i] = pixels.getPixelColor(i); + } + + switch (ledTaskParams) { + case LED_POWER_TEST: + ledRainbow(20); + pixels.clear(); + break; + case LED_EFFECT_WIFI_CONNECT_ERROR: + blinkDelayTwoColor(100, 3, pixels.Color(8, 161, 236), + pixels.Color(255, 0, 0)); + break; + case LED_FLASH_ERROR: + blinkDelayColor(250, 3, 255, 0, 0); + break; + case LED_EFFECT_HEARTBEAT: + blinkDelayColor(150, 2, 0, 0, 255); + break; + case LED_DATA_BLOCK_ERROR: + blinkDelayColor(150, 2, 128, 0, 128); + break; + case LED_DATA_PRICE_ERROR: + blinkDelayColor(150, 2, 177, 90, 31); + break; + case LED_EFFECT_WIFI_CONNECT_SUCCESS: + case LED_FLASH_SUCCESS: + blinkDelayColor(150, 3, 0, 255, 0); + break; + case LED_PROGRESS_100: + pixels.setPixelColor(0, pixels.Color(0, 255, 0)); + case LED_PROGRESS_75: + pixels.setPixelColor(1, pixels.Color(0, 255, 0)); + case LED_PROGRESS_50: + pixels.setPixelColor(2, pixels.Color(0, 255, 0)); + case LED_PROGRESS_25: + pixels.setPixelColor(3, pixels.Color(0, 255, 0)); + pixels.show(); + break; + case LED_FLASH_UPDATE: + break; + case LED_FLASH_BLOCK_NOTIFY: + blinkDelayTwoColor(250, 3, pixels.Color(224, 67, 0), + pixels.Color(8, 2, 0)); + break; + case LED_EFFECT_WIFI_WAIT_FOR_CONFIG: + blinkDelayTwoColor(100, 1, pixels.Color(8, 161, 236), + pixels.Color(156, 225, 240)); + break; + case LED_EFFECT_WIFI_ERASE_SETTINGS: + blinkDelay(100, 3); + break; + case LED_EFFECT_WIFI_CONNECTING: + for (int i = NEOPIXEL_COUNT; i >= 0; i--) { + for (int j = NEOPIXEL_COUNT; j >= 0; j--) { + if (j == i) { + pixels.setPixelColor(i, pixels.Color(16, 197, 236)); + } else { + pixels.setPixelColor(j, pixels.Color(0, 0, 0)); } - - std::array oldLights; - for (int i = 0; i < NEOPIXEL_COUNT; i++) { - oldLights[i] = handler->pixels.getPixelColor(i); - } - -#ifdef HAS_FRONTLIGHT - uint flDelayTime = preferences.getUInt("flEffectDelay"); -#endif - - switch (handler->ledTaskParams) { - case LED_POWER_TEST: -#ifdef HAS_FRONTLIGHT - handler->frontlightFadeInAll(preferences.getUInt("flEffectDelay"), true); -#endif - handler->rainbow(20); - handler->pixels.clear(); - break; - - case LED_EFFECT_WIFI_CONNECT_ERROR: - handler->blinkDelayTwoColor(100, 3, handler->pixels.Color(8, 161, 236), - handler->pixels.Color(255, 0, 0)); - break; - - case LED_EFFECT_CONFIGURING: - for (int i = NEOPIXEL_COUNT; i--; i > 0) { - for (int j = NEOPIXEL_COUNT; j--; j > 0) { - uint32_t c = handler->pixels.Color(0, 0, 0); - if (i == j) - c = handler->pixels.Color(0, 0, 255); - handler->pixels.setPixelColor(j, c); - } - handler->pixels.show(); - delay(100); - } - handler->pixels.clear(); - handler->pixels.show(); - break; - - case LED_FLASH_ERROR: - handler->blinkDelayColor(250, 3, 255, 0, 0); - break; - - case LED_EFFECT_HEARTBEAT: - handler->blinkDelayColor(150, 2, 0, 0, 255); - break; - - case LED_DATA_BLOCK_ERROR: - handler->blinkDelayColor(150, 2, 128, 0, 128); - break; - - case LED_DATA_PRICE_ERROR: - handler->blinkDelayColor(150, 2, 177, 90, 31); - break; - - case LED_FLASH_IDENTIFY: - handler->blinkDelayTwoColor(100, 2, handler->pixels.Color(255, 0, 0), - handler->pixels.Color(0, 255, 255)); - handler->blinkDelayTwoColor(100, 2, handler->pixels.Color(0, 255, 0), - handler->pixels.Color(0, 0, 255)); - break; - - case LED_EFFECT_WIFI_CONNECT_SUCCESS: - case LED_FLASH_SUCCESS: - handler->blinkDelayColor(150, 3, 0, 255, 0); - break; - - case LED_PROGRESS_100: - handler->pixels.setPixelColor(0, handler->pixels.Color(0, 255, 0)); - [[fallthrough]]; - case LED_PROGRESS_75: - handler->pixels.setPixelColor(1, handler->pixels.Color(0, 255, 0)); - [[fallthrough]]; - case LED_PROGRESS_50: - handler->pixels.setPixelColor(2, handler->pixels.Color(0, 255, 0)); - [[fallthrough]]; - case LED_PROGRESS_25: - handler->pixels.setPixelColor(3, handler->pixels.Color(0, 255, 0)); - handler->pixels.show(); - break; - - case LED_EFFECT_NOSTR_ZAP: - { -#ifdef HAS_FRONTLIGHT - bool frontlightWasOn = false; - if (preferences.getBool("flFlashOnZap", DEFAULT_FL_FLASH_ON_ZAP)) { - if (handler->frontlightOn) { - frontlightWasOn = true; - handler->frontlightFadeOutAll(flDelayTime, true); - } else { - handler->frontlightFadeInAll(flDelayTime, true); - } - } -#endif - for (int flash = 0; flash < random(7, 10); flash++) { - handler->lightningStrike(); - delay(random(50, 150)); - } -#ifdef HAS_FRONTLIGHT - if (preferences.getBool("flFlashOnZap", DEFAULT_FL_FLASH_ON_ZAP)) { - vTaskDelay(pdMS_TO_TICKS(10)); - if (frontlightWasOn) { - handler->frontlightFadeInAll(flDelayTime, true); - } else { - handler->frontlightFadeOutAll(flDelayTime, true); - } - } -#endif - break; - } - - case LED_FLASH_UPDATE: - handler->blinkDelayTwoColor(250, 3, handler->pixels.Color(0, 230, 0), - handler->pixels.Color(230, 230, 0)); - break; - - case LED_FLASH_BLOCK_NOTIFY: - { -#ifdef HAS_FRONTLIGHT - bool frontlightWasOn = false; - if (preferences.getBool("flFlashOnUpd", DEFAULT_FL_FLASH_ON_UPDATE)) { - if (handler->frontlightOn) { - frontlightWasOn = true; - handler->frontlightFadeOutAll(flDelayTime, true); - } else { - handler->frontlightFadeInAll(flDelayTime, true); - } - } -#endif - handler->blinkDelayTwoColor(250, 3, handler->pixels.Color(224, 67, 0), - handler->pixels.Color(8, 2, 0)); -#ifdef HAS_FRONTLIGHT - if (preferences.getBool("flFlashOnUpd", DEFAULT_FL_FLASH_ON_UPDATE)) { - vTaskDelay(pdMS_TO_TICKS(10)); - if (frontlightWasOn) { - handler->frontlightFadeInAll(flDelayTime, true); - } else { - handler->frontlightFadeOutAll(flDelayTime, true); - } - } -#endif - break; - } - - case LED_EFFECT_WIFI_WAIT_FOR_CONFIG: - handler->blinkDelayTwoColor(100, 1, handler->pixels.Color(8, 161, 236), - handler->pixels.Color(156, 225, 240)); - break; - - case LED_EFFECT_WIFI_ERASE_SETTINGS: - handler->blinkDelay(100, 3); - break; - - case LED_EFFECT_WIFI_CONNECTING: - for (int i = NEOPIXEL_COUNT; i >= 0; i--) { - for (int j = NEOPIXEL_COUNT; j >= 0; j--) { - if (j == i) { - handler->pixels.setPixelColor(i, handler->pixels.Color(16, 197, 236)); - } else { - handler->pixels.setPixelColor(j, handler->pixels.Color(0, 0, 0)); - } - } - handler->pixels.show(); - vTaskDelay(pdMS_TO_TICKS(100)); - } - break; - - case LED_EFFECT_PAUSE_TIMER: - for (int i = NEOPIXEL_COUNT; i >= 0; i--) { - for (int j = NEOPIXEL_COUNT; j >= 0; j--) { - uint32_t c = handler->pixels.Color(0, 0, 0); - if (i == j) - c = handler->pixels.Color(0, 255, 0); - handler->pixels.setPixelColor(j, c); - } - handler->pixels.show(); - delay(100); - } - handler->pixels.setPixelColor(0, handler->pixels.Color(255, 0, 0)); - handler->pixels.show(); - delay(900); - handler->pixels.clear(); - handler->pixels.show(); - break; - - case LED_EFFECT_START_TIMER: - handler->pixels.clear(); - handler->pixels.setPixelColor((NEOPIXEL_COUNT - 1), handler->pixels.Color(255, 0, 0)); - handler->pixels.show(); - delay(900); - for (int i = NEOPIXEL_COUNT; i--; i > 0) { - for (int j = NEOPIXEL_COUNT; j--; j > 0) { - uint32_t c = handler->pixels.Color(0, 0, 0); - if (i == j) - c = handler->pixels.Color(0, 255, 0); - handler->pixels.setPixelColor(j, c); - } - handler->pixels.show(); - delay(100); - } - handler->pixels.clear(); - handler->pixels.show(); - break; - } - - // Restore previous state unless power test - for (int i = 0; i < NEOPIXEL_COUNT; i++) { - handler->pixels.setPixelColor(i, oldLights[i]); - } - handler->pixels.show(); + } + pixels.show(); + vTaskDelay(pdMS_TO_TICKS(100)); } + break; + case LED_EFFECT_PAUSE_TIMER: + for (int i = NEOPIXEL_COUNT; i >= 0; i--) { + for (int j = NEOPIXEL_COUNT; j >= 0; j--) { + uint32_t c = pixels.Color(0, 0, 0); + if (i == j) c = pixels.Color(0, 255, 0); + pixels.setPixelColor(j, c); + } + + pixels.show(); + + delay(100); + } + pixels.setPixelColor(0, pixels.Color(255, 0, 0)); + pixels.show(); + + delay(900); + + pixels.clear(); + pixels.show(); + break; + case LED_EFFECT_START_TIMER: + pixels.clear(); + pixels.setPixelColor((NEOPIXEL_COUNT - 1), pixels.Color(255, 0, 0)); + pixels.show(); + + delay(900); + + for (int i = NEOPIXEL_COUNT; i--; i > 0) { + for (int j = NEOPIXEL_COUNT; j--; j > 0) { + uint32_t c = pixels.Color(0, 0, 0); + if (i == j) c = pixels.Color(0, 255, 0); + + pixels.setPixelColor(j, c); + } + + pixels.show(); + + delay(100); + } + + pixels.clear(); + pixels.show(); + break; } + + // revert to previous state unless power test + + for (int i = 0; i < NEOPIXEL_COUNT; i++) { + pixels.setPixelColor(i, oldLights[i]); + } + + pixels.show(); + } } + } } -bool LedHandler::queueEffect(uint effect) { - if (isDNDActive()) { - return false; +void setupLeds() { + pixels.begin(); + pixels.setBrightness(preferences.getUInt("ledBrightness", 128)); + pixels.clear(); + pixels.show(); + setupLedTask(); + if (preferences.getBool("ledTestOnPower", true)) { + while (!ledTaskQueue) { + delay(1); + // wait until queue is available } - if (ledTaskQueue == nullptr) { - return false; - } - xQueueSend(ledTaskQueue, &effect, portMAX_DELAY); - return true; + queueLedEffect(LED_POWER_TEST); + } } -void LedHandler::clear() { - preferences.putBool("ledStatus", false); - pixels.clear(); +void setupLedTask() { + ledTaskQueue = xQueueCreate(5, sizeof(uint)); + + xTaskCreate(ledTask, "LedTask", 2048, NULL, tskIDLE_PRIORITY, &ledTaskHandle); +} + +void blinkDelay(int d, int times) { + for (int j = 0; j < times; j++) { + pixels.setPixelColor(0, pixels.Color(255, 0, 0)); + pixels.setPixelColor(1, pixels.Color(0, 255, 0)); + pixels.setPixelColor(2, pixels.Color(255, 0, 0)); + pixels.setPixelColor(3, pixels.Color(0, 255, 0)); pixels.show(); + vTaskDelay(pdMS_TO_TICKS(d)); + + pixels.setPixelColor(0, pixels.Color(255, 255, 0)); + pixels.setPixelColor(1, pixels.Color(0, 255, 255)); + pixels.setPixelColor(2, pixels.Color(255, 255, 0)); + pixels.setPixelColor(3, pixels.Color(0, 255, 255)); + pixels.show(); + vTaskDelay(pdMS_TO_TICKS(d)); + } + pixels.clear(); + pixels.show(); } -void LedHandler::setLights(int r, int g, int b) { - setLights(pixels.Color(r, g, b)); -} - -void LedHandler::setLights(uint32_t color) { - bool ledStatus = true; +void blinkDelayColor(int d, int times, uint r, uint g, uint b) { + for (int j = 0; j < times; j++) { for (int i = 0; i < NEOPIXEL_COUNT; i++) { - pixels.setPixelColor(i, color); + pixels.setPixelColor(i, pixels.Color(r, g, b)); } + pixels.show(); + vTaskDelay(pdMS_TO_TICKS(d)); - if (color == pixels.Color(0, 0, 0)) { - ledStatus = false; - } else { - saveLedState(); - } - preferences.putBool("ledStatus", ledStatus); -} - -void LedHandler::saveLedState() { - for (int i = 0; i < pixels.numPixels(); i++) { - int pixelColor = pixels.getPixelColor(i); - char key[12]; - snprintf(key, 12, "%s%d", "ledColor_", i); - preferences.putUInt(key, pixelColor); - } - xTaskNotifyGive(eventSourceTaskHandle); -} - -void LedHandler::restoreLedState() { - for (int i = 0; i < pixels.numPixels(); i++) { - char key[12]; - snprintf(key, 12, "%s%d", "ledColor_", i); - uint pixelColor = preferences.getUInt(key, pixels.Color(0, 0, 0)); - pixels.setPixelColor(i, pixelColor); - } - pixels.show(); -} - -void LedHandler::rainbow(int wait) { - for (long firstPixelHue = 0; firstPixelHue < 5 * 65536; firstPixelHue += 256) { - pixels.rainbow(firstPixelHue); - pixels.show(); - delayMicroseconds(wait); - } -} - -void LedHandler::theaterChase(uint32_t color, int wait) { - for (int a = 0; a < 10; a++) { - for (int b = 0; b < 3; b++) { - pixels.clear(); - for (int c = b; c < pixels.numPixels(); c += 3) { - pixels.setPixelColor(c, color); - } - pixels.show(); - vTaskDelay(pdMS_TO_TICKS(wait)); - } - } -} - -void LedHandler::theaterChaseRainbow(int wait) { - int firstPixelHue = 0; - for (int a = 0; a < 30; a++) { - for (int b = 0; b < 3; b++) { - pixels.clear(); - for (int c = b; c < pixels.numPixels(); c += 3) { - int hue = firstPixelHue + c * 65536L / pixels.numPixels(); - uint32_t color = pixels.gamma32(pixels.ColorHSV(hue)); - pixels.setPixelColor(c, color); - } - pixels.show(); - vTaskDelay(pdMS_TO_TICKS(wait)); - firstPixelHue += 65536 / 90; - } - } -} - -void LedHandler::lightningStrike() { - uint32_t PURPLE = pixels.Color(128, 0, 128); - uint32_t YELLOW = pixels.Color(255, 226, 41); - - for (int i = 0; i < pixels.numPixels(); i++) { - pixels.setPixelColor(i, random(2) == 0 ? YELLOW : PURPLE); - } - pixels.show(); - delay(random(10, 50)); -} - -void LedHandler::blinkDelay(int d, int times) { - for (int j = 0; j < times; j++) { - pixels.setPixelColor(0, pixels.Color(255, 0, 0)); - pixels.setPixelColor(1, pixels.Color(0, 255, 0)); - pixels.setPixelColor(2, pixels.Color(255, 0, 0)); - pixels.setPixelColor(3, pixels.Color(0, 255, 0)); - pixels.show(); - vTaskDelay(pdMS_TO_TICKS(d)); - - pixels.setPixelColor(0, pixels.Color(255, 255, 0)); - pixels.setPixelColor(1, pixels.Color(0, 255, 255)); - pixels.setPixelColor(2, pixels.Color(255, 255, 0)); - pixels.setPixelColor(3, pixels.Color(0, 255, 255)); - pixels.show(); - vTaskDelay(pdMS_TO_TICKS(d)); - } pixels.clear(); pixels.show(); + vTaskDelay(pdMS_TO_TICKS(d)); + } + pixels.clear(); + pixels.show(); } -void LedHandler::blinkDelayColor(int d, int times, uint r, uint g, uint b) { - for (int j = 0; j < times; j++) { - for (int i = 0; i < NEOPIXEL_COUNT; i++) { - pixels.setPixelColor(i, pixels.Color(r, g, b)); - } - pixels.show(); - vTaskDelay(pdMS_TO_TICKS(d)); - - pixels.clear(); - pixels.show(); - vTaskDelay(pdMS_TO_TICKS(d)); +void blinkDelayTwoColor(int d, int times, uint32_t c1, uint32_t c2) { + for (int j = 0; j < times; j++) { + for (int i = 0; i < NEOPIXEL_COUNT; i++) { + pixels.setPixelColor(i, c1); } - pixels.clear(); pixels.show(); -} + vTaskDelay(pdMS_TO_TICKS(d)); -void LedHandler::blinkDelayTwoColor(int d, int times, const uint32_t& c1, const uint32_t& c2) { - for (int j = 0; j < times; j++) { - for (int i = 0; i < NEOPIXEL_COUNT; i++) { - pixels.setPixelColor(i, c1); - } - pixels.show(); - vTaskDelay(pdMS_TO_TICKS(d)); - - for (int i = 0; i < NEOPIXEL_COUNT; i++) { - pixels.setPixelColor(i, c2); - } - pixels.show(); - vTaskDelay(pdMS_TO_TICKS(d)); + for (int i = 0; i < NEOPIXEL_COUNT; i++) { + pixels.setPixelColor(i, c2); } - pixels.clear(); pixels.show(); + vTaskDelay(pdMS_TO_TICKS(d)); + } + pixels.clear(); + pixels.show(); } -// DND Implementation -void LedHandler::loadDNDSettings() { - dndEnabled = preferences.getBool("dndEnabled", false); - dndTimeBasedEnabled = preferences.getBool("dndTimeEnabled", false); - - dndTimeRange.startHour = preferences.getUChar("dndStartHour", 23); - dndTimeRange.startMinute = preferences.getUChar("dndStartMin", 0); - dndTimeRange.endHour = preferences.getUChar("dndEndHour", 7); - dndTimeRange.endMinute = preferences.getUChar("dndEndMin", 0); +void clearLeds() { + preferences.putBool("ledStatus", false); + pixels.clear(); + pixels.show(); } -void LedHandler::setDNDEnabled(bool enabled) { - dndEnabled = enabled; - preferences.putBool("dndEnabled", enabled); - if (enabled && isDNDActive()) { - clear(); -#ifdef HAS_FRONTLIGHT - frontlightFadeOutAll(); -#endif - } +void setLights(int r, int g, int b) { setLights(pixels.Color(r, g, b)); } + +void setLights(uint32_t color) { + bool ledStatus = true; + + for (int i = 0; i < NEOPIXEL_COUNT; i++) { + pixels.setPixelColor(i, color); + } + pixels.show(); + + if (color == pixels.Color(0, 0, 0)) { + ledStatus = false; + } else { + saveLedState(); + } + preferences.putBool("ledStatus", ledStatus); } -void LedHandler::setDNDTimeBasedEnabled(bool enabled) { - dndTimeBasedEnabled = enabled; - preferences.putBool("dndTimeEnabled", enabled); - if (enabled && isDNDActive()) { - clear(); -#ifdef HAS_FRONTLIGHT - frontlightFadeOutAll(); -#endif - } +void saveLedState() { + for (int i = 0; i < pixels.numPixels(); i++) { + int pixelColor = pixels.getPixelColor(i); + char key[12]; + snprintf(key, 12, "%s%d", "ledColor_", i); + preferences.putUInt(key, pixelColor); + } + + xTaskNotifyGive(eventSourceTaskHandle); } -void LedHandler::setDNDTimeRange(uint8_t startHour, uint8_t startMinute, uint8_t endHour, uint8_t endMinute) { - dndTimeRange.startHour = startHour; - dndTimeRange.startMinute = startMinute; - dndTimeRange.endHour = endHour; - dndTimeRange.endMinute = endMinute; - - preferences.putUChar("dndStartHour", startHour); - preferences.putUChar("dndStartMin", startMinute); - preferences.putUChar("dndEndHour", endHour); - preferences.putUChar("dndEndMin", endMinute); +void restoreLedState() { + for (int i = 0; i < pixels.numPixels(); i++) { + char key[12]; + snprintf(key, 12, "%s%d", "ledColor_", i); + uint pixelColor = preferences.getUInt(key, pixels.Color(0, 0, 0)); + pixels.setPixelColor(i, pixelColor); + } + + pixels.show(); } -bool LedHandler::isTimeInDNDRange(uint8_t hour, uint8_t minute) const { - uint16_t currentTime = hour * 60 + minute; - uint16_t startTime = dndTimeRange.startHour * 60 + dndTimeRange.startMinute; - uint16_t endTime = dndTimeRange.endHour * 60 + dndTimeRange.endMinute; - - if (startTime <= endTime) { - return currentTime >= startTime && currentTime < endTime; - } else { - return currentTime >= startTime || currentTime < endTime; - } -} +QueueHandle_t getLedTaskQueue() { return ledTaskQueue; } -bool LedHandler::isDNDActive() const { - if (dndEnabled) { - return true; - } - - if (dndTimeBasedEnabled) { - time_t now; - struct tm timeinfo; - time(&now); - localtime_r(&now, &timeinfo); - return isTimeInDNDRange(timeinfo.tm_hour, timeinfo.tm_min); - } - +bool queueLedEffect(uint effect) { + if (ledTaskQueue == NULL) { return false; + } + + uint flashType = effect; + xQueueSend(ledTaskQueue, &flashType, portMAX_DELAY); } -#ifdef HAS_FRONTLIGHT -// Frontlight implementation -void LedHandler::frontlightFlash(int flDelayTime) { - if (preferences.getBool("flDisable")) { - return; - } - - if (frontlightOn) { - frontlightFadeOutAll(flDelayTime, true); - frontlightFadeInAll(flDelayTime, true); - } else { - frontlightFadeInAll(flDelayTime, true); - frontlightFadeOutAll(flDelayTime, true); - } +void ledRainbow(int wait) { + // Hue of first pixel runs 5 complete loops through the color wheel. + // Color wheel has a range of 65536 but it's OK if we roll over, so + // just count from 0 to 5*65536. Adding 256 to firstPixelHue each time + // means we'll make 5*65536/256 = 1280 passes through this loop: + for (long firstPixelHue = 0; firstPixelHue < 5 * 65536; + firstPixelHue += 256) { + // strip.rainbow() can take a single argument (first pixel hue) or + // optionally a few extras: number of rainbow repetitions (default 1), + // saturation and value (brightness) (both 0-255, similar to the + // ColorHSV() function, default 255), and a true/false flag for whether + // to apply gamma correction to provide 'truer' colors (default true). + pixels.rainbow(firstPixelHue); + // Above line is equivalent to: + // strip.rainbow(firstPixelHue, 1, 255, 255, true); + pixels.show(); // Update strip with new contents + delayMicroseconds(wait); + // vTaskDelay(pdMS_TO_TICKS(wait)); // Pause for a moment + } } -void LedHandler::frontlightFadeInAll() { - frontlightFadeInAll(preferences.getUInt("flEffectDelay")); +void ledTheaterChase(uint32_t color, int wait) { + for (int a = 0; a < 10; a++) { // Repeat 10 times... + for (int b = 0; b < 3; b++) { // 'b' counts from 0 to 2... + pixels.clear(); // Set all pixels in RAM to 0 (off) + // 'c' counts up from 'b' to end of strip in steps of 3... + for (int c = b; c < pixels.numPixels(); c += 3) { + pixels.setPixelColor(c, color); // Set pixel 'c' to value 'color' + } + pixels.show(); // Update strip with new contents + vTaskDelay(pdMS_TO_TICKS(wait)); // Pause for a moment + } + } } -void LedHandler::frontlightFadeOutAll() { - frontlightFadeOutAll(preferences.getUInt("flEffectDelay")); +void ledTheaterChaseRainbow(int wait) { + int firstPixelHue = 0; // First pixel starts at red (hue 0) + for (int a = 0; a < 30; a++) { // Repeat 30 times... + for (int b = 0; b < 3; b++) { // 'b' counts from 0 to 2... + pixels.clear(); // Set all pixels in RAM to 0 (off) + // 'c' counts up from 'b' to end of strip in increments of 3... + for (int c = b; c < pixels.numPixels(); c += 3) { + // hue of pixel 'c' is offset by an amount to make one full + // revolution of the color wheel (range 65536) along the length + // of the strip (strip.numPixels() steps): + int hue = firstPixelHue + c * 65536L / pixels.numPixels(); + uint32_t color = pixels.gamma32(pixels.ColorHSV(hue)); // hue -> RGB + pixels.setPixelColor(c, color); // Set pixel 'c' to value 'color' + } + pixels.show(); // Update strip with new contents + vTaskDelay(pdMS_TO_TICKS(wait)); // Pause for a moment + firstPixelHue += 65536 / 90; // One cycle of color wheel over 90 frames + } + } } -void LedHandler::frontlightFadeIn(uint num) { - frontlightFadeIn(num, preferences.getUInt("flEffectDelay")); -} - -void LedHandler::frontlightFadeOut(uint num) { - frontlightFadeOut(num, preferences.getUInt("flEffectDelay")); -} - -void LedHandler::frontlightSetBrightness(uint brightness) { - if (isDNDActive() || brightness > 4096) { - return; - } - - for (int ledPin = 0; ledPin <= NUM_SCREENS; ledPin++) { - flArray.setPWM(ledPin + 1, 0, brightness); - } -} - -std::vector LedHandler::frontlightGetStatus() { - std::vector statuses; - for (int ledPin = 1; ledPin <= NUM_SCREENS; ledPin++) { - uint16_t a = 0, b = 0; - flArray.getPWM(ledPin + 1, &a, &b); - statuses.push_back(round(b - a / 4096)); - } - return statuses; -} - -void LedHandler::frontlightFadeInAll(int flDelayTime, bool staggered) { - if (preferences.getBool("flDisable") || frontlightIsOn() || flInTransition) { - return; - } - - flInTransition = true; - const int maxBrightness = preferences.getUInt("flMaxBrightness"); - - if (staggered) { - int step = FL_FADE_STEP; - int staggerDelay = flDelayTime / NUM_SCREENS; - - for (int dutyCycle = 0; dutyCycle <= maxBrightness + (NUM_SCREENS - 1) * maxBrightness / NUM_SCREENS; dutyCycle += step) { - for (int ledPin = 0; ledPin < NUM_SCREENS; ledPin++) { - int ledBrightness = dutyCycle - ledPin * maxBrightness / NUM_SCREENS; - if (ledBrightness < 0) { - ledBrightness = 0; - } else if (ledBrightness > maxBrightness) { - ledBrightness = maxBrightness; - } - flArray.setPWM(ledPin + 1, 0, ledBrightness); - } - vTaskDelay(pdMS_TO_TICKS(staggerDelay)); - } - } else { - for (int dutyCycle = 0; dutyCycle <= maxBrightness; dutyCycle += FL_FADE_STEP) { - for (int ledPin = 0; ledPin <= NUM_SCREENS; ledPin++) { - flArray.setPWM(ledPin + 1, 0, dutyCycle); - } - vTaskDelay(pdMS_TO_TICKS(flDelayTime)); - } - } - frontlightOn = true; - flInTransition = false; -} - -void LedHandler::frontlightFadeOutAll(int flDelayTime, bool staggered) { - if (preferences.getBool("flDisable") || !frontlightIsOn() || flInTransition) { - return; - } - - flInTransition = true; - if (staggered) { - int maxBrightness = preferences.getUInt("flMaxBrightness"); - int step = FL_FADE_STEP; - int staggerDelay = flDelayTime / NUM_SCREENS; - - for (int dutyCycle = maxBrightness; dutyCycle >= 0; dutyCycle -= step) { - for (int ledPin = 0; ledPin < NUM_SCREENS; ledPin++) { - int ledBrightness = dutyCycle - (NUM_SCREENS - 1 - ledPin) * maxBrightness / NUM_SCREENS; - if (ledBrightness < 0) { - ledBrightness = 0; - } else if (ledBrightness > maxBrightness) { - ledBrightness = maxBrightness; - } - flArray.setPWM(ledPin + 1, 0, ledBrightness); - } - vTaskDelay(pdMS_TO_TICKS(staggerDelay)); - } - } else { - for (int dutyCycle = preferences.getUInt("flMaxBrightness"); dutyCycle >= 0; dutyCycle -= FL_FADE_STEP) { - for (int ledPin = 0; ledPin <= NUM_SCREENS; ledPin++) { - flArray.setPWM(ledPin + 1, 0, dutyCycle); - } - vTaskDelay(pdMS_TO_TICKS(flDelayTime)); - } - } - - flArray.allOFF(); - frontlightOn = false; - flInTransition = false; -} - -void LedHandler::frontlightFadeIn(uint num, int flDelayTime) { - if (isDNDActive() || preferences.getBool("flDisable")) { - return; - } - - for (int dutyCycle = 0; dutyCycle <= preferences.getUInt("flMaxBrightness"); dutyCycle += 5) { - flArray.setPWM(num + 1, 0, dutyCycle); - vTaskDelay(pdMS_TO_TICKS(flDelayTime)); - } -} - -void LedHandler::frontlightFadeOut(uint num, int flDelayTime) { - if (isDNDActive() || preferences.getBool("flDisable") || !frontlightIsOn()) { - return; - } - - for (int dutyCycle = preferences.getUInt("flMaxBrightness"); dutyCycle >= 0; dutyCycle -= 5) { - flArray.setPWM(num + 1, 0, dutyCycle); - vTaskDelay(pdMS_TO_TICKS(flDelayTime)); - } -} - -void LedHandler::initializeFrontlight() { - if (!flArray.begin(PCA9685_MODE1_AUTOINCR | PCA9685_MODE1_ALLCALL, PCA9685_MODE2_TOTEMPOLE)) - { - Serial.println(F("FL driver error")); - return; - } - flArray.setFrequency(200); - Serial.println(F("FL driver active")); - - if (!preferences.isKey("flMaxBrightness")) - { - preferences.putUInt("flMaxBrightness", DEFAULT_FL_MAX_BRIGHTNESS); - } - if (!preferences.isKey("flEffectDelay")) - { - preferences.putUInt("flEffectDelay", DEFAULT_FL_EFFECT_DELAY); - } - - if (!preferences.isKey("flFlashOnUpd")) - { - preferences.putBool("flFlashOnUpd", DEFAULT_FL_FLASH_ON_UPDATE); - } -} -#endif +Adafruit_NeoPixel getPixels() { return pixels; } \ No newline at end of file diff --git a/src/lib/led_handler.hpp b/src/lib/led_handler.hpp index e599e2a..8e064f5 100644 --- a/src/lib/led_handler.hpp +++ b/src/lib/led_handler.hpp @@ -4,7 +4,6 @@ #include #include #include -#include #include "lib/shared.hpp" #include "lib/webserver.hpp" @@ -16,120 +15,45 @@ #define NEOPIXEL_COUNT 4 #endif -// LED effect constants const int LED_FLASH_ERROR = 0; const int LED_FLASH_SUCCESS = 1; const int LED_FLASH_UPDATE = 2; -const int LED_EFFECT_CONFIGURING = 10; -const int LED_FLASH_BLOCK_NOTIFY = 4; -const int LED_EFFECT_START_TIMER = 5; -const int LED_EFFECT_PAUSE_TIMER = 6; -const int LED_EFFECT_HEARTBEAT = 7; +const int LED_FLASH_BLOCK_NOTIFY = 3; +const int LED_EFFECT_START_TIMER = 4; +const int LED_EFFECT_PAUSE_TIMER = 5; +const int LED_EFFECT_HEARTBEAT = 6; const int LED_EFFECT_WIFI_WAIT_FOR_CONFIG = 100; const int LED_EFFECT_WIFI_CONNECTING = 101; const int LED_EFFECT_WIFI_CONNECT_ERROR = 102; const int LED_EFFECT_WIFI_CONNECT_SUCCESS = 103; const int LED_EFFECT_WIFI_ERASE_SETTINGS = 104; + const int LED_PROGRESS_25 = 200; const int LED_PROGRESS_50 = 201; const int LED_PROGRESS_75 = 202; const int LED_PROGRESS_100 = 203; + const int LED_DATA_PRICE_ERROR = 300; const int LED_DATA_BLOCK_ERROR = 301; -const int LED_EFFECT_NOSTR_ZAP = 400; -const int LED_FLASH_IDENTIFY = 990; + const int LED_POWER_TEST = 999; +extern TaskHandle_t ledTaskHandle; +extern Adafruit_NeoPixel pixels; -// Do Not Disturb mode settings -struct DNDTimeRange { - uint8_t startHour; - uint8_t startMinute; - uint8_t endHour; - uint8_t endMinute; -}; - -class LedHandler { -public: - static LedHandler& getInstance(); - - // Delete copy constructor and assignment operator - LedHandler(const LedHandler&) = delete; - LedHandler& operator=(const LedHandler&) = delete; - - void setup(); - void setupTask(); - bool queueEffect(uint effect); - void clear(); - void setLights(int r, int g, int b); - void setLights(uint32_t color); - void saveLedState(); - void restoreLedState(); - QueueHandle_t getTaskQueue() const { return ledTaskQueue; } - Adafruit_NeoPixel& getPixels() { return pixels; } - - // DND methods - void setDNDEnabled(bool enabled); - void setDNDTimeBasedEnabled(bool enabled); - void setDNDTimeRange(uint8_t startHour, uint8_t startMinute, uint8_t endHour, uint8_t endMinute); - bool isDNDActive() const; - bool isTimeInDNDRange(uint8_t hour, uint8_t minute) const; - - // DND getters - bool isDNDEnabled() const { return dndEnabled; } - bool isDNDTimeBasedEnabled() const { return dndTimeBasedEnabled; } - uint8_t getDNDStartHour() const { return dndTimeRange.startHour; } - uint8_t getDNDStartMinute() const { return dndTimeRange.startMinute; } - uint8_t getDNDEndHour() const { return dndTimeRange.endHour; } - uint8_t getDNDEndMinute() const { return dndTimeRange.endMinute; } - - // Effect methods - void rainbow(int wait); - void theaterChase(uint32_t color, int wait); - void theaterChaseRainbow(int wait); - void lightningStrike(); - void blinkDelay(int d, int times); - void blinkDelayColor(int d, int times, uint r, uint g, uint b); - void blinkDelayTwoColor(int d, int times, const uint32_t& c1, const uint32_t& c2); - -#ifdef HAS_FRONTLIGHT - void frontlightFlash(int flDelayTime); - void frontlightFadeInAll(); - void frontlightFadeOutAll(); - void frontlightFadeIn(uint num); - void frontlightFadeOut(uint num); - std::vector frontlightGetStatus(); - void frontlightSetBrightness(uint brightness); - bool frontlightIsOn() const { return frontlightOn; } - void frontlightFadeInAll(int flDelayTime, bool staggered = false); - void frontlightFadeOutAll(int flDelayTime, bool staggered = false); - void frontlightFadeIn(uint num, int flDelayTime); - void frontlightFadeOut(uint num, int flDelayTime); - void initializeFrontlight(); -#endif - -private: - LedHandler(); // Private constructor for singleton - void loadDNDSettings(); - static void ledTask(void* pvParameters); - - Adafruit_NeoPixel pixels; - TaskHandle_t ledTaskHandle; - QueueHandle_t ledTaskQueue; - uint ledTaskParams; - - // DND members - bool dndEnabled; - bool dndTimeBasedEnabled; - DNDTimeRange dndTimeRange; - -#ifdef HAS_FRONTLIGHT - static constexpr uint16_t FL_FADE_STEP = 25; - bool frontlightOn; - bool flInTransition; -#endif -}; - -// Global accessor function -inline LedHandler& getLedHandler() { - return LedHandler::getInstance(); -} \ No newline at end of file +void ledTask(void *pvParameters); +void setupLeds(); +void setupLedTask(); +void blinkDelay(int d, int times); +void blinkDelayColor(int d, int times, uint r, uint g, uint b); +void blinkDelayTwoColor(int d, int times, uint32_t c1, uint32_t c2); +void clearLeds(); +void saveLedState(); +void restoreLedState(); +QueueHandle_t getLedTaskQueue(); +bool queueLedEffect(uint effect); +void setLights(int r, int g, int b); +void setLights(uint32_t color); +void ledRainbow(int wait); +void ledTheaterChaseRainbow(int wait); +void ledTheaterChase(uint32_t color, int wait); +Adafruit_NeoPixel getPixels(); \ No newline at end of file diff --git a/src/lib/littlefs/lfs.c b/src/lib/littlefs/lfs.c new file mode 100644 index 0000000..a0bd76f --- /dev/null +++ b/src/lib/littlefs/lfs.c @@ -0,0 +1,6457 @@ +/* + * The little filesystem + * + * Copyright (c) 2022, The littlefs authors. + * Copyright (c) 2017, Arm Limited. All rights reserved. + * SPDX-License-Identifier: BSD-3-Clause + */ +#include "lfs.h" +#include "lfs_util.h" + + +// some constants used throughout the code +#define LFS_BLOCK_NULL ((lfs_block_t)-1) +#define LFS_BLOCK_INLINE ((lfs_block_t)-2) + +enum { + LFS_OK_RELOCATED = 1, + LFS_OK_DROPPED = 2, + LFS_OK_ORPHANED = 3, +}; + +enum { + LFS_CMP_EQ = 0, + LFS_CMP_LT = 1, + LFS_CMP_GT = 2, +}; + + +/// Caching block device operations /// + +static inline void lfs_cache_drop(lfs_t *lfs, lfs_cache_t *rcache) { + // do not zero, cheaper if cache is readonly or only going to be + // written with identical data (during relocates) + (void)lfs; + rcache->block = LFS_BLOCK_NULL; +} + +static inline void lfs_cache_zero(lfs_t *lfs, lfs_cache_t *pcache) { + // zero to avoid information leak + memset(pcache->buffer, 0xff, lfs->cfg->cache_size); + pcache->block = LFS_BLOCK_NULL; +} + +static int lfs_bd_read(lfs_t *lfs, + const lfs_cache_t *pcache, lfs_cache_t *rcache, lfs_size_t hint, + lfs_block_t block, lfs_off_t off, + void *buffer, lfs_size_t size) { + uint8_t *data = buffer; + if (off+size > lfs->cfg->block_size + || (lfs->block_count && block >= lfs->block_count)) { + return LFS_ERR_CORRUPT; + } + + while (size > 0) { + lfs_size_t diff = size; + + if (pcache && block == pcache->block && + off < pcache->off + pcache->size) { + if (off >= pcache->off) { + // is already in pcache? + diff = lfs_min(diff, pcache->size - (off-pcache->off)); + memcpy(data, &pcache->buffer[off-pcache->off], diff); + + data += diff; + off += diff; + size -= diff; + continue; + } + + // pcache takes priority + diff = lfs_min(diff, pcache->off-off); + } + + if (block == rcache->block && + off < rcache->off + rcache->size) { + if (off >= rcache->off) { + // is already in rcache? + diff = lfs_min(diff, rcache->size - (off-rcache->off)); + memcpy(data, &rcache->buffer[off-rcache->off], diff); + + data += diff; + off += diff; + size -= diff; + continue; + } + + // rcache takes priority + diff = lfs_min(diff, rcache->off-off); + } + + if (size >= hint && off % lfs->cfg->read_size == 0 && + size >= lfs->cfg->read_size) { + // bypass cache? + diff = lfs_aligndown(diff, lfs->cfg->read_size); + int err = lfs->cfg->read(lfs->cfg, block, off, data, diff); + if (err) { + return err; + } + + data += diff; + off += diff; + size -= diff; + continue; + } + + // load to cache, first condition can no longer fail + LFS_ASSERT(!lfs->block_count || block < lfs->block_count); + rcache->block = block; + rcache->off = lfs_aligndown(off, lfs->cfg->read_size); + rcache->size = lfs_min( + lfs_min( + lfs_alignup(off+hint, lfs->cfg->read_size), + lfs->cfg->block_size) + - rcache->off, + lfs->cfg->cache_size); + int err = lfs->cfg->read(lfs->cfg, rcache->block, + rcache->off, rcache->buffer, rcache->size); + LFS_ASSERT(err <= 0); + if (err) { + return err; + } + } + + return 0; +} + +static int lfs_bd_cmp(lfs_t *lfs, + const lfs_cache_t *pcache, lfs_cache_t *rcache, lfs_size_t hint, + lfs_block_t block, lfs_off_t off, + const void *buffer, lfs_size_t size) { + const uint8_t *data = buffer; + lfs_size_t diff = 0; + + for (lfs_off_t i = 0; i < size; i += diff) { + uint8_t dat[8]; + + diff = lfs_min(size-i, sizeof(dat)); + int err = lfs_bd_read(lfs, + pcache, rcache, hint-i, + block, off+i, &dat, diff); + if (err) { + return err; + } + + int res = memcmp(dat, data + i, diff); + if (res) { + return res < 0 ? LFS_CMP_LT : LFS_CMP_GT; + } + } + + return LFS_CMP_EQ; +} + +static int lfs_bd_crc(lfs_t *lfs, + const lfs_cache_t *pcache, lfs_cache_t *rcache, lfs_size_t hint, + lfs_block_t block, lfs_off_t off, lfs_size_t size, uint32_t *crc) { + lfs_size_t diff = 0; + + for (lfs_off_t i = 0; i < size; i += diff) { + uint8_t dat[8]; + diff = lfs_min(size-i, sizeof(dat)); + int err = lfs_bd_read(lfs, + pcache, rcache, hint-i, + block, off+i, &dat, diff); + if (err) { + return err; + } + + *crc = lfs_crc(*crc, &dat, diff); + } + + return 0; +} + +#ifndef LFS_READONLY +static int lfs_bd_flush(lfs_t *lfs, + lfs_cache_t *pcache, lfs_cache_t *rcache, bool validate) { + if (pcache->block != LFS_BLOCK_NULL && pcache->block != LFS_BLOCK_INLINE) { + LFS_ASSERT(pcache->block < lfs->block_count); + lfs_size_t diff = lfs_alignup(pcache->size, lfs->cfg->prog_size); + int err = lfs->cfg->prog(lfs->cfg, pcache->block, + pcache->off, pcache->buffer, diff); + LFS_ASSERT(err <= 0); + if (err) { + return err; + } + + if (validate) { + // check data on disk + lfs_cache_drop(lfs, rcache); + int res = lfs_bd_cmp(lfs, + NULL, rcache, diff, + pcache->block, pcache->off, pcache->buffer, diff); + if (res < 0) { + return res; + } + + if (res != LFS_CMP_EQ) { + return LFS_ERR_CORRUPT; + } + } + + lfs_cache_zero(lfs, pcache); + } + + return 0; +} +#endif + +#ifndef LFS_READONLY +static int lfs_bd_sync(lfs_t *lfs, + lfs_cache_t *pcache, lfs_cache_t *rcache, bool validate) { + lfs_cache_drop(lfs, rcache); + + int err = lfs_bd_flush(lfs, pcache, rcache, validate); + if (err) { + return err; + } + + err = lfs->cfg->sync(lfs->cfg); + LFS_ASSERT(err <= 0); + return err; +} +#endif + +#ifndef LFS_READONLY +static int lfs_bd_prog(lfs_t *lfs, + lfs_cache_t *pcache, lfs_cache_t *rcache, bool validate, + lfs_block_t block, lfs_off_t off, + const void *buffer, lfs_size_t size) { + const uint8_t *data = buffer; + LFS_ASSERT(block == LFS_BLOCK_INLINE || block < lfs->block_count); + LFS_ASSERT(off + size <= lfs->cfg->block_size); + + while (size > 0) { + if (block == pcache->block && + off >= pcache->off && + off < pcache->off + lfs->cfg->cache_size) { + // already fits in pcache? + lfs_size_t diff = lfs_min(size, + lfs->cfg->cache_size - (off-pcache->off)); + memcpy(&pcache->buffer[off-pcache->off], data, diff); + + data += diff; + off += diff; + size -= diff; + + pcache->size = lfs_max(pcache->size, off - pcache->off); + if (pcache->size == lfs->cfg->cache_size) { + // eagerly flush out pcache if we fill up + int err = lfs_bd_flush(lfs, pcache, rcache, validate); + if (err) { + return err; + } + } + + continue; + } + + // pcache must have been flushed, either by programming and + // entire block or manually flushing the pcache + LFS_ASSERT(pcache->block == LFS_BLOCK_NULL); + + // prepare pcache, first condition can no longer fail + pcache->block = block; + pcache->off = lfs_aligndown(off, lfs->cfg->prog_size); + pcache->size = 0; + } + + return 0; +} +#endif + +#ifndef LFS_READONLY +static int lfs_bd_erase(lfs_t *lfs, lfs_block_t block) { + LFS_ASSERT(block < lfs->block_count); + int err = lfs->cfg->erase(lfs->cfg, block); + LFS_ASSERT(err <= 0); + return err; +} +#endif + + +/// Small type-level utilities /// +// operations on block pairs +static inline void lfs_pair_swap(lfs_block_t pair[2]) { + lfs_block_t t = pair[0]; + pair[0] = pair[1]; + pair[1] = t; +} + +static inline bool lfs_pair_isnull(const lfs_block_t pair[2]) { + return pair[0] == LFS_BLOCK_NULL || pair[1] == LFS_BLOCK_NULL; +} + +static inline int lfs_pair_cmp( + const lfs_block_t paira[2], + const lfs_block_t pairb[2]) { + return !(paira[0] == pairb[0] || paira[1] == pairb[1] || + paira[0] == pairb[1] || paira[1] == pairb[0]); +} + +static inline bool lfs_pair_issync( + const lfs_block_t paira[2], + const lfs_block_t pairb[2]) { + return (paira[0] == pairb[0] && paira[1] == pairb[1]) || + (paira[0] == pairb[1] && paira[1] == pairb[0]); +} + +static inline void lfs_pair_fromle32(lfs_block_t pair[2]) { + pair[0] = lfs_fromle32(pair[0]); + pair[1] = lfs_fromle32(pair[1]); +} + +#ifndef LFS_READONLY +static inline void lfs_pair_tole32(lfs_block_t pair[2]) { + pair[0] = lfs_tole32(pair[0]); + pair[1] = lfs_tole32(pair[1]); +} +#endif + +// operations on 32-bit entry tags +typedef uint32_t lfs_tag_t; +typedef int32_t lfs_stag_t; + +#define LFS_MKTAG(type, id, size) \ + (((lfs_tag_t)(type) << 20) | ((lfs_tag_t)(id) << 10) | (lfs_tag_t)(size)) + +#define LFS_MKTAG_IF(cond, type, id, size) \ + ((cond) ? LFS_MKTAG(type, id, size) : LFS_MKTAG(LFS_FROM_NOOP, 0, 0)) + +#define LFS_MKTAG_IF_ELSE(cond, type1, id1, size1, type2, id2, size2) \ + ((cond) ? LFS_MKTAG(type1, id1, size1) : LFS_MKTAG(type2, id2, size2)) + +static inline bool lfs_tag_isvalid(lfs_tag_t tag) { + return !(tag & 0x80000000); +} + +static inline bool lfs_tag_isdelete(lfs_tag_t tag) { + return ((int32_t)(tag << 22) >> 22) == -1; +} + +static inline uint16_t lfs_tag_type1(lfs_tag_t tag) { + return (tag & 0x70000000) >> 20; +} + +static inline uint16_t lfs_tag_type2(lfs_tag_t tag) { + return (tag & 0x78000000) >> 20; +} + +static inline uint16_t lfs_tag_type3(lfs_tag_t tag) { + return (tag & 0x7ff00000) >> 20; +} + +static inline uint8_t lfs_tag_chunk(lfs_tag_t tag) { + return (tag & 0x0ff00000) >> 20; +} + +static inline int8_t lfs_tag_splice(lfs_tag_t tag) { + return (int8_t)lfs_tag_chunk(tag); +} + +static inline uint16_t lfs_tag_id(lfs_tag_t tag) { + return (tag & 0x000ffc00) >> 10; +} + +static inline lfs_size_t lfs_tag_size(lfs_tag_t tag) { + return tag & 0x000003ff; +} + +static inline lfs_size_t lfs_tag_dsize(lfs_tag_t tag) { + return sizeof(tag) + lfs_tag_size(tag + lfs_tag_isdelete(tag)); +} + +// operations on attributes in attribute lists +struct lfs_mattr { + lfs_tag_t tag; + const void *buffer; +}; + +struct lfs_diskoff { + lfs_block_t block; + lfs_off_t off; +}; + +#define LFS_MKATTRS(...) \ + (struct lfs_mattr[]){__VA_ARGS__}, \ + sizeof((struct lfs_mattr[]){__VA_ARGS__}) / sizeof(struct lfs_mattr) + +// operations on global state +static inline void lfs_gstate_xor(lfs_gstate_t *a, const lfs_gstate_t *b) { + for (int i = 0; i < 3; i++) { + ((uint32_t*)a)[i] ^= ((const uint32_t*)b)[i]; + } +} + +static inline bool lfs_gstate_iszero(const lfs_gstate_t *a) { + for (int i = 0; i < 3; i++) { + if (((uint32_t*)a)[i] != 0) { + return false; + } + } + return true; +} + +#ifndef LFS_READONLY +static inline bool lfs_gstate_hasorphans(const lfs_gstate_t *a) { + return lfs_tag_size(a->tag); +} + +static inline uint8_t lfs_gstate_getorphans(const lfs_gstate_t *a) { + return lfs_tag_size(a->tag) & 0x1ff; +} + +static inline bool lfs_gstate_hasmove(const lfs_gstate_t *a) { + return lfs_tag_type1(a->tag); +} +#endif + +static inline bool lfs_gstate_needssuperblock(const lfs_gstate_t *a) { + return lfs_tag_size(a->tag) >> 9; +} + +static inline bool lfs_gstate_hasmovehere(const lfs_gstate_t *a, + const lfs_block_t *pair) { + return lfs_tag_type1(a->tag) && lfs_pair_cmp(a->pair, pair) == 0; +} + +static inline void lfs_gstate_fromle32(lfs_gstate_t *a) { + a->tag = lfs_fromle32(a->tag); + a->pair[0] = lfs_fromle32(a->pair[0]); + a->pair[1] = lfs_fromle32(a->pair[1]); +} + +#ifndef LFS_READONLY +static inline void lfs_gstate_tole32(lfs_gstate_t *a) { + a->tag = lfs_tole32(a->tag); + a->pair[0] = lfs_tole32(a->pair[0]); + a->pair[1] = lfs_tole32(a->pair[1]); +} +#endif + +// operations on forward-CRCs used to track erased state +struct lfs_fcrc { + lfs_size_t size; + uint32_t crc; +}; + +static void lfs_fcrc_fromle32(struct lfs_fcrc *fcrc) { + fcrc->size = lfs_fromle32(fcrc->size); + fcrc->crc = lfs_fromle32(fcrc->crc); +} + +#ifndef LFS_READONLY +static void lfs_fcrc_tole32(struct lfs_fcrc *fcrc) { + fcrc->size = lfs_tole32(fcrc->size); + fcrc->crc = lfs_tole32(fcrc->crc); +} +#endif + +// other endianness operations +static void lfs_ctz_fromle32(struct lfs_ctz *ctz) { + ctz->head = lfs_fromle32(ctz->head); + ctz->size = lfs_fromle32(ctz->size); +} + +#ifndef LFS_READONLY +static void lfs_ctz_tole32(struct lfs_ctz *ctz) { + ctz->head = lfs_tole32(ctz->head); + ctz->size = lfs_tole32(ctz->size); +} +#endif + +static inline void lfs_superblock_fromle32(lfs_superblock_t *superblock) { + superblock->version = lfs_fromle32(superblock->version); + superblock->block_size = lfs_fromle32(superblock->block_size); + superblock->block_count = lfs_fromle32(superblock->block_count); + superblock->name_max = lfs_fromle32(superblock->name_max); + superblock->file_max = lfs_fromle32(superblock->file_max); + superblock->attr_max = lfs_fromle32(superblock->attr_max); +} + +#ifndef LFS_READONLY +static inline void lfs_superblock_tole32(lfs_superblock_t *superblock) { + superblock->version = lfs_tole32(superblock->version); + superblock->block_size = lfs_tole32(superblock->block_size); + superblock->block_count = lfs_tole32(superblock->block_count); + superblock->name_max = lfs_tole32(superblock->name_max); + superblock->file_max = lfs_tole32(superblock->file_max); + superblock->attr_max = lfs_tole32(superblock->attr_max); +} +#endif + +#ifndef LFS_NO_ASSERT +static bool lfs_mlist_isopen(struct lfs_mlist *head, + struct lfs_mlist *node) { + for (struct lfs_mlist **p = &head; *p; p = &(*p)->next) { + if (*p == (struct lfs_mlist*)node) { + return true; + } + } + + return false; +} +#endif + +static void lfs_mlist_remove(lfs_t *lfs, struct lfs_mlist *mlist) { + for (struct lfs_mlist **p = &lfs->mlist; *p; p = &(*p)->next) { + if (*p == mlist) { + *p = (*p)->next; + break; + } + } +} + +static void lfs_mlist_append(lfs_t *lfs, struct lfs_mlist *mlist) { + mlist->next = lfs->mlist; + lfs->mlist = mlist; +} + +// some other filesystem operations +static uint32_t lfs_fs_disk_version(lfs_t *lfs) { + (void)lfs; +#ifdef LFS_MULTIVERSION + if (lfs->cfg->disk_version) { + return lfs->cfg->disk_version; + } else +#endif + { + return LFS_DISK_VERSION; + } +} + +static uint16_t lfs_fs_disk_version_major(lfs_t *lfs) { + return 0xffff & (lfs_fs_disk_version(lfs) >> 16); + +} + +static uint16_t lfs_fs_disk_version_minor(lfs_t *lfs) { + return 0xffff & (lfs_fs_disk_version(lfs) >> 0); +} + + +/// Internal operations predeclared here /// +#ifndef LFS_READONLY +static int lfs_dir_commit(lfs_t *lfs, lfs_mdir_t *dir, + const struct lfs_mattr *attrs, int attrcount); +static int lfs_dir_compact(lfs_t *lfs, + lfs_mdir_t *dir, const struct lfs_mattr *attrs, int attrcount, + lfs_mdir_t *source, uint16_t begin, uint16_t end); +static lfs_ssize_t lfs_file_flushedwrite(lfs_t *lfs, lfs_file_t *file, + const void *buffer, lfs_size_t size); +static lfs_ssize_t lfs_file_write_(lfs_t *lfs, lfs_file_t *file, + const void *buffer, lfs_size_t size); +static int lfs_file_sync_(lfs_t *lfs, lfs_file_t *file); +static int lfs_file_outline(lfs_t *lfs, lfs_file_t *file); +static int lfs_file_flush(lfs_t *lfs, lfs_file_t *file); + +static int lfs_fs_deorphan(lfs_t *lfs, bool powerloss); +static int lfs_fs_preporphans(lfs_t *lfs, int8_t orphans); +static void lfs_fs_prepmove(lfs_t *lfs, + uint16_t id, const lfs_block_t pair[2]); +static int lfs_fs_pred(lfs_t *lfs, const lfs_block_t dir[2], + lfs_mdir_t *pdir); +static lfs_stag_t lfs_fs_parent(lfs_t *lfs, const lfs_block_t dir[2], + lfs_mdir_t *parent); +static int lfs_fs_forceconsistency(lfs_t *lfs); +#endif + +static void lfs_fs_prepsuperblock(lfs_t *lfs, bool needssuperblock); + +#ifdef LFS_MIGRATE +static int lfs1_traverse(lfs_t *lfs, + int (*cb)(void*, lfs_block_t), void *data); +#endif + +static int lfs_dir_rewind_(lfs_t *lfs, lfs_dir_t *dir); + +static lfs_ssize_t lfs_file_flushedread(lfs_t *lfs, lfs_file_t *file, + void *buffer, lfs_size_t size); +static lfs_ssize_t lfs_file_read_(lfs_t *lfs, lfs_file_t *file, + void *buffer, lfs_size_t size); +static int lfs_file_close_(lfs_t *lfs, lfs_file_t *file); +static lfs_soff_t lfs_file_size_(lfs_t *lfs, lfs_file_t *file); + +static lfs_ssize_t lfs_fs_size_(lfs_t *lfs); +static int lfs_fs_traverse_(lfs_t *lfs, + int (*cb)(void *data, lfs_block_t block), void *data, + bool includeorphans); + +static int lfs_deinit(lfs_t *lfs); +static int lfs_unmount_(lfs_t *lfs); + + +/// Block allocator /// + +// allocations should call this when all allocated blocks are committed to +// the filesystem +// +// after a checkpoint, the block allocator may realloc any untracked blocks +static void lfs_alloc_ckpoint(lfs_t *lfs) { + lfs->lookahead.ckpoint = lfs->block_count; +} + +// drop the lookahead buffer, this is done during mounting and failed +// traversals in order to avoid invalid lookahead state +static void lfs_alloc_drop(lfs_t *lfs) { + lfs->lookahead.size = 0; + lfs->lookahead.next = 0; + lfs_alloc_ckpoint(lfs); +} + +#ifndef LFS_READONLY +static int lfs_alloc_lookahead(void *p, lfs_block_t block) { + lfs_t *lfs = (lfs_t*)p; + lfs_block_t off = ((block - lfs->lookahead.start) + + lfs->block_count) % lfs->block_count; + + if (off < lfs->lookahead.size) { + lfs->lookahead.buffer[off / 8] |= 1U << (off % 8); + } + + return 0; +} +#endif + +#ifndef LFS_READONLY +static int lfs_alloc_scan(lfs_t *lfs) { + // move lookahead buffer to the first unused block + // + // note we limit the lookahead buffer to at most the amount of blocks + // checkpointed, this prevents the math in lfs_alloc from underflowing + lfs->lookahead.start = (lfs->lookahead.start + lfs->lookahead.next) + % lfs->block_count; + lfs->lookahead.next = 0; + lfs->lookahead.size = lfs_min( + 8*lfs->cfg->lookahead_size, + lfs->lookahead.ckpoint); + + // find mask of free blocks from tree + memset(lfs->lookahead.buffer, 0, lfs->cfg->lookahead_size); + int err = lfs_fs_traverse_(lfs, lfs_alloc_lookahead, lfs, true); + if (err) { + lfs_alloc_drop(lfs); + return err; + } + + return 0; +} +#endif + +#ifndef LFS_READONLY +static int lfs_alloc(lfs_t *lfs, lfs_block_t *block) { + while (true) { + // scan our lookahead buffer for free blocks + while (lfs->lookahead.next < lfs->lookahead.size) { + if (!(lfs->lookahead.buffer[lfs->lookahead.next / 8] + & (1U << (lfs->lookahead.next % 8)))) { + // found a free block + *block = (lfs->lookahead.start + lfs->lookahead.next) + % lfs->block_count; + + // eagerly find next free block to maximize how many blocks + // lfs_alloc_ckpoint makes available for scanning + while (true) { + lfs->lookahead.next += 1; + lfs->lookahead.ckpoint -= 1; + + if (lfs->lookahead.next >= lfs->lookahead.size + || !(lfs->lookahead.buffer[lfs->lookahead.next / 8] + & (1U << (lfs->lookahead.next % 8)))) { + return 0; + } + } + } + + lfs->lookahead.next += 1; + lfs->lookahead.ckpoint -= 1; + } + + // In order to keep our block allocator from spinning forever when our + // filesystem is full, we mark points where there are no in-flight + // allocations with a checkpoint before starting a set of allocations. + // + // If we've looked at all blocks since the last checkpoint, we report + // the filesystem as out of storage. + // + if (lfs->lookahead.ckpoint <= 0) { + LFS_ERROR("No more free space 0x%"PRIx32, + (lfs->lookahead.start + lfs->lookahead.next) + % lfs->cfg->block_count); + return LFS_ERR_NOSPC; + } + + // No blocks in our lookahead buffer, we need to scan the filesystem for + // unused blocks in the next lookahead window. + int err = lfs_alloc_scan(lfs); + if(err) { + return err; + } + } +} +#endif + +/// Metadata pair and directory operations /// +static lfs_stag_t lfs_dir_getslice(lfs_t *lfs, const lfs_mdir_t *dir, + lfs_tag_t gmask, lfs_tag_t gtag, + lfs_off_t goff, void *gbuffer, lfs_size_t gsize) { + lfs_off_t off = dir->off; + lfs_tag_t ntag = dir->etag; + lfs_stag_t gdiff = 0; + + // synthetic moves + if (lfs_gstate_hasmovehere(&lfs->gdisk, dir->pair) && + lfs_tag_id(gmask) != 0) { + if (lfs_tag_id(lfs->gdisk.tag) == lfs_tag_id(gtag)) { + return LFS_ERR_NOENT; + } else if (lfs_tag_id(lfs->gdisk.tag) < lfs_tag_id(gtag)) { + gdiff -= LFS_MKTAG(0, 1, 0); + } + } + + // iterate over dir block backwards (for faster lookups) + while (off >= sizeof(lfs_tag_t) + lfs_tag_dsize(ntag)) { + off -= lfs_tag_dsize(ntag); + lfs_tag_t tag = ntag; + int err = lfs_bd_read(lfs, + NULL, &lfs->rcache, sizeof(ntag), + dir->pair[0], off, &ntag, sizeof(ntag)); + if (err) { + return err; + } + + ntag = (lfs_frombe32(ntag) ^ tag) & 0x7fffffff; + + if (lfs_tag_id(gmask) != 0 && + lfs_tag_type1(tag) == LFS_TYPE_SPLICE && + lfs_tag_id(tag) <= lfs_tag_id(gtag - gdiff)) { + if (tag == (LFS_MKTAG(LFS_TYPE_CREATE, 0, 0) | + (LFS_MKTAG(0, 0x3ff, 0) & (gtag - gdiff)))) { + // found where we were created + return LFS_ERR_NOENT; + } + + // move around splices + gdiff += LFS_MKTAG(0, lfs_tag_splice(tag), 0); + } + + if ((gmask & tag) == (gmask & (gtag - gdiff))) { + if (lfs_tag_isdelete(tag)) { + return LFS_ERR_NOENT; + } + + lfs_size_t diff = lfs_min(lfs_tag_size(tag), gsize); + err = lfs_bd_read(lfs, + NULL, &lfs->rcache, diff, + dir->pair[0], off+sizeof(tag)+goff, gbuffer, diff); + if (err) { + return err; + } + + memset((uint8_t*)gbuffer + diff, 0, gsize - diff); + + return tag + gdiff; + } + } + + return LFS_ERR_NOENT; +} + +static lfs_stag_t lfs_dir_get(lfs_t *lfs, const lfs_mdir_t *dir, + lfs_tag_t gmask, lfs_tag_t gtag, void *buffer) { + return lfs_dir_getslice(lfs, dir, + gmask, gtag, + 0, buffer, lfs_tag_size(gtag)); +} + +static int lfs_dir_getread(lfs_t *lfs, const lfs_mdir_t *dir, + const lfs_cache_t *pcache, lfs_cache_t *rcache, lfs_size_t hint, + lfs_tag_t gmask, lfs_tag_t gtag, + lfs_off_t off, void *buffer, lfs_size_t size) { + uint8_t *data = buffer; + if (off+size > lfs->cfg->block_size) { + return LFS_ERR_CORRUPT; + } + + while (size > 0) { + lfs_size_t diff = size; + + if (pcache && pcache->block == LFS_BLOCK_INLINE && + off < pcache->off + pcache->size) { + if (off >= pcache->off) { + // is already in pcache? + diff = lfs_min(diff, pcache->size - (off-pcache->off)); + memcpy(data, &pcache->buffer[off-pcache->off], diff); + + data += diff; + off += diff; + size -= diff; + continue; + } + + // pcache takes priority + diff = lfs_min(diff, pcache->off-off); + } + + if (rcache->block == LFS_BLOCK_INLINE && + off < rcache->off + rcache->size) { + if (off >= rcache->off) { + // is already in rcache? + diff = lfs_min(diff, rcache->size - (off-rcache->off)); + memcpy(data, &rcache->buffer[off-rcache->off], diff); + + data += diff; + off += diff; + size -= diff; + continue; + } + + // rcache takes priority + diff = lfs_min(diff, rcache->off-off); + } + + // load to cache, first condition can no longer fail + rcache->block = LFS_BLOCK_INLINE; + rcache->off = lfs_aligndown(off, lfs->cfg->read_size); + rcache->size = lfs_min(lfs_alignup(off+hint, lfs->cfg->read_size), + lfs->cfg->cache_size); + int err = lfs_dir_getslice(lfs, dir, gmask, gtag, + rcache->off, rcache->buffer, rcache->size); + if (err < 0) { + return err; + } + } + + return 0; +} + +#ifndef LFS_READONLY +static int lfs_dir_traverse_filter(void *p, + lfs_tag_t tag, const void *buffer) { + lfs_tag_t *filtertag = p; + (void)buffer; + + // which mask depends on unique bit in tag structure + uint32_t mask = (tag & LFS_MKTAG(0x100, 0, 0)) + ? LFS_MKTAG(0x7ff, 0x3ff, 0) + : LFS_MKTAG(0x700, 0x3ff, 0); + + // check for redundancy + if ((mask & tag) == (mask & *filtertag) || + lfs_tag_isdelete(*filtertag) || + (LFS_MKTAG(0x7ff, 0x3ff, 0) & tag) == ( + LFS_MKTAG(LFS_TYPE_DELETE, 0, 0) | + (LFS_MKTAG(0, 0x3ff, 0) & *filtertag))) { + *filtertag = LFS_MKTAG(LFS_FROM_NOOP, 0, 0); + return true; + } + + // check if we need to adjust for created/deleted tags + if (lfs_tag_type1(tag) == LFS_TYPE_SPLICE && + lfs_tag_id(tag) <= lfs_tag_id(*filtertag)) { + *filtertag += LFS_MKTAG(0, lfs_tag_splice(tag), 0); + } + + return false; +} +#endif + +#ifndef LFS_READONLY +// maximum recursive depth of lfs_dir_traverse, the deepest call: +// +// traverse with commit +// '-> traverse with move +// '-> traverse with filter +// +#define LFS_DIR_TRAVERSE_DEPTH 3 + +struct lfs_dir_traverse { + const lfs_mdir_t *dir; + lfs_off_t off; + lfs_tag_t ptag; + const struct lfs_mattr *attrs; + int attrcount; + + lfs_tag_t tmask; + lfs_tag_t ttag; + uint16_t begin; + uint16_t end; + int16_t diff; + + int (*cb)(void *data, lfs_tag_t tag, const void *buffer); + void *data; + + lfs_tag_t tag; + const void *buffer; + struct lfs_diskoff disk; +}; + +static int lfs_dir_traverse(lfs_t *lfs, + const lfs_mdir_t *dir, lfs_off_t off, lfs_tag_t ptag, + const struct lfs_mattr *attrs, int attrcount, + lfs_tag_t tmask, lfs_tag_t ttag, + uint16_t begin, uint16_t end, int16_t diff, + int (*cb)(void *data, lfs_tag_t tag, const void *buffer), void *data) { + // This function in inherently recursive, but bounded. To allow tool-based + // analysis without unnecessary code-cost we use an explicit stack + struct lfs_dir_traverse stack[LFS_DIR_TRAVERSE_DEPTH-1]; + unsigned sp = 0; + int res; + + // iterate over directory and attrs + lfs_tag_t tag; + const void *buffer; + struct lfs_diskoff disk = {0}; + while (true) { + { + if (off+lfs_tag_dsize(ptag) < dir->off) { + off += lfs_tag_dsize(ptag); + int err = lfs_bd_read(lfs, + NULL, &lfs->rcache, sizeof(tag), + dir->pair[0], off, &tag, sizeof(tag)); + if (err) { + return err; + } + + tag = (lfs_frombe32(tag) ^ ptag) | 0x80000000; + disk.block = dir->pair[0]; + disk.off = off+sizeof(lfs_tag_t); + buffer = &disk; + ptag = tag; + } else if (attrcount > 0) { + tag = attrs[0].tag; + buffer = attrs[0].buffer; + attrs += 1; + attrcount -= 1; + } else { + // finished traversal, pop from stack? + res = 0; + break; + } + + // do we need to filter? + lfs_tag_t mask = LFS_MKTAG(0x7ff, 0, 0); + if ((mask & tmask & tag) != (mask & tmask & ttag)) { + continue; + } + + if (lfs_tag_id(tmask) != 0) { + LFS_ASSERT(sp < LFS_DIR_TRAVERSE_DEPTH); + // recurse, scan for duplicates, and update tag based on + // creates/deletes + stack[sp] = (struct lfs_dir_traverse){ + .dir = dir, + .off = off, + .ptag = ptag, + .attrs = attrs, + .attrcount = attrcount, + .tmask = tmask, + .ttag = ttag, + .begin = begin, + .end = end, + .diff = diff, + .cb = cb, + .data = data, + .tag = tag, + .buffer = buffer, + .disk = disk, + }; + sp += 1; + + tmask = 0; + ttag = 0; + begin = 0; + end = 0; + diff = 0; + cb = lfs_dir_traverse_filter; + data = &stack[sp-1].tag; + continue; + } + } + +popped: + // in filter range? + if (lfs_tag_id(tmask) != 0 && + !(lfs_tag_id(tag) >= begin && lfs_tag_id(tag) < end)) { + continue; + } + + // handle special cases for mcu-side operations + if (lfs_tag_type3(tag) == LFS_FROM_NOOP) { + // do nothing + } else if (lfs_tag_type3(tag) == LFS_FROM_MOVE) { + // Without this condition, lfs_dir_traverse can exhibit an + // extremely expensive O(n^3) of nested loops when renaming. + // This happens because lfs_dir_traverse tries to filter tags by + // the tags in the source directory, triggering a second + // lfs_dir_traverse with its own filter operation. + // + // traverse with commit + // '-> traverse with filter + // '-> traverse with move + // '-> traverse with filter + // + // However we don't actually care about filtering the second set of + // tags, since duplicate tags have no effect when filtering. + // + // This check skips this unnecessary recursive filtering explicitly, + // reducing this runtime from O(n^3) to O(n^2). + if (cb == lfs_dir_traverse_filter) { + continue; + } + + // recurse into move + stack[sp] = (struct lfs_dir_traverse){ + .dir = dir, + .off = off, + .ptag = ptag, + .attrs = attrs, + .attrcount = attrcount, + .tmask = tmask, + .ttag = ttag, + .begin = begin, + .end = end, + .diff = diff, + .cb = cb, + .data = data, + .tag = LFS_MKTAG(LFS_FROM_NOOP, 0, 0), + }; + sp += 1; + + uint16_t fromid = lfs_tag_size(tag); + uint16_t toid = lfs_tag_id(tag); + dir = buffer; + off = 0; + ptag = 0xffffffff; + attrs = NULL; + attrcount = 0; + tmask = LFS_MKTAG(0x600, 0x3ff, 0); + ttag = LFS_MKTAG(LFS_TYPE_STRUCT, 0, 0); + begin = fromid; + end = fromid+1; + diff = toid-fromid+diff; + } else if (lfs_tag_type3(tag) == LFS_FROM_USERATTRS) { + for (unsigned i = 0; i < lfs_tag_size(tag); i++) { + const struct lfs_attr *a = buffer; + res = cb(data, LFS_MKTAG(LFS_TYPE_USERATTR + a[i].type, + lfs_tag_id(tag) + diff, a[i].size), a[i].buffer); + if (res < 0) { + return res; + } + + if (res) { + break; + } + } + } else { + res = cb(data, tag + LFS_MKTAG(0, diff, 0), buffer); + if (res < 0) { + return res; + } + + if (res) { + break; + } + } + } + + if (sp > 0) { + // pop from the stack and return, fortunately all pops share + // a destination + dir = stack[sp-1].dir; + off = stack[sp-1].off; + ptag = stack[sp-1].ptag; + attrs = stack[sp-1].attrs; + attrcount = stack[sp-1].attrcount; + tmask = stack[sp-1].tmask; + ttag = stack[sp-1].ttag; + begin = stack[sp-1].begin; + end = stack[sp-1].end; + diff = stack[sp-1].diff; + cb = stack[sp-1].cb; + data = stack[sp-1].data; + tag = stack[sp-1].tag; + buffer = stack[sp-1].buffer; + disk = stack[sp-1].disk; + sp -= 1; + goto popped; + } else { + return res; + } +} +#endif + +static lfs_stag_t lfs_dir_fetchmatch(lfs_t *lfs, + lfs_mdir_t *dir, const lfs_block_t pair[2], + lfs_tag_t fmask, lfs_tag_t ftag, uint16_t *id, + int (*cb)(void *data, lfs_tag_t tag, const void *buffer), void *data) { + // we can find tag very efficiently during a fetch, since we're already + // scanning the entire directory + lfs_stag_t besttag = -1; + + // if either block address is invalid we return LFS_ERR_CORRUPT here, + // otherwise later writes to the pair could fail + if (lfs->block_count + && (pair[0] >= lfs->block_count || pair[1] >= lfs->block_count)) { + return LFS_ERR_CORRUPT; + } + + // find the block with the most recent revision + uint32_t revs[2] = {0, 0}; + int r = 0; + for (int i = 0; i < 2; i++) { + int err = lfs_bd_read(lfs, + NULL, &lfs->rcache, sizeof(revs[i]), + pair[i], 0, &revs[i], sizeof(revs[i])); + revs[i] = lfs_fromle32(revs[i]); + if (err && err != LFS_ERR_CORRUPT) { + return err; + } + + if (err != LFS_ERR_CORRUPT && + lfs_scmp(revs[i], revs[(i+1)%2]) > 0) { + r = i; + } + } + + dir->pair[0] = pair[(r+0)%2]; + dir->pair[1] = pair[(r+1)%2]; + dir->rev = revs[(r+0)%2]; + dir->off = 0; // nonzero = found some commits + + // now scan tags to fetch the actual dir and find possible match + for (int i = 0; i < 2; i++) { + lfs_off_t off = 0; + lfs_tag_t ptag = 0xffffffff; + + uint16_t tempcount = 0; + lfs_block_t temptail[2] = {LFS_BLOCK_NULL, LFS_BLOCK_NULL}; + bool tempsplit = false; + lfs_stag_t tempbesttag = besttag; + + // assume not erased until proven otherwise + bool maybeerased = false; + bool hasfcrc = false; + struct lfs_fcrc fcrc; + + dir->rev = lfs_tole32(dir->rev); + uint32_t crc = lfs_crc(0xffffffff, &dir->rev, sizeof(dir->rev)); + dir->rev = lfs_fromle32(dir->rev); + + while (true) { + // extract next tag + lfs_tag_t tag; + off += lfs_tag_dsize(ptag); + int err = lfs_bd_read(lfs, + NULL, &lfs->rcache, lfs->cfg->block_size, + dir->pair[0], off, &tag, sizeof(tag)); + if (err) { + if (err == LFS_ERR_CORRUPT) { + // can't continue? + break; + } + return err; + } + + crc = lfs_crc(crc, &tag, sizeof(tag)); + tag = lfs_frombe32(tag) ^ ptag; + + // next commit not yet programmed? + if (!lfs_tag_isvalid(tag)) { + // we only might be erased if the last tag was a crc + maybeerased = (lfs_tag_type2(ptag) == LFS_TYPE_CCRC); + break; + // out of range? + } else if (off + lfs_tag_dsize(tag) > lfs->cfg->block_size) { + break; + } + + ptag = tag; + + if (lfs_tag_type2(tag) == LFS_TYPE_CCRC) { + // check the crc attr + uint32_t dcrc; + err = lfs_bd_read(lfs, + NULL, &lfs->rcache, lfs->cfg->block_size, + dir->pair[0], off+sizeof(tag), &dcrc, sizeof(dcrc)); + if (err) { + if (err == LFS_ERR_CORRUPT) { + break; + } + return err; + } + dcrc = lfs_fromle32(dcrc); + + if (crc != dcrc) { + break; + } + + // reset the next bit if we need to + ptag ^= (lfs_tag_t)(lfs_tag_chunk(tag) & 1U) << 31; + + // toss our crc into the filesystem seed for + // pseudorandom numbers, note we use another crc here + // as a collection function because it is sufficiently + // random and convenient + lfs->seed = lfs_crc(lfs->seed, &crc, sizeof(crc)); + + // update with what's found so far + besttag = tempbesttag; + dir->off = off + lfs_tag_dsize(tag); + dir->etag = ptag; + dir->count = tempcount; + dir->tail[0] = temptail[0]; + dir->tail[1] = temptail[1]; + dir->split = tempsplit; + + // reset crc, hasfcrc + crc = 0xffffffff; + continue; + } + + // crc the entry first, hopefully leaving it in the cache + err = lfs_bd_crc(lfs, + NULL, &lfs->rcache, lfs->cfg->block_size, + dir->pair[0], off+sizeof(tag), + lfs_tag_dsize(tag)-sizeof(tag), &crc); + if (err) { + if (err == LFS_ERR_CORRUPT) { + break; + } + return err; + } + + // directory modification tags? + if (lfs_tag_type1(tag) == LFS_TYPE_NAME) { + // increase count of files if necessary + if (lfs_tag_id(tag) >= tempcount) { + tempcount = lfs_tag_id(tag) + 1; + } + } else if (lfs_tag_type1(tag) == LFS_TYPE_SPLICE) { + tempcount += lfs_tag_splice(tag); + + if (tag == (LFS_MKTAG(LFS_TYPE_DELETE, 0, 0) | + (LFS_MKTAG(0, 0x3ff, 0) & tempbesttag))) { + tempbesttag |= 0x80000000; + } else if (tempbesttag != -1 && + lfs_tag_id(tag) <= lfs_tag_id(tempbesttag)) { + tempbesttag += LFS_MKTAG(0, lfs_tag_splice(tag), 0); + } + } else if (lfs_tag_type1(tag) == LFS_TYPE_TAIL) { + tempsplit = (lfs_tag_chunk(tag) & 1); + + err = lfs_bd_read(lfs, + NULL, &lfs->rcache, lfs->cfg->block_size, + dir->pair[0], off+sizeof(tag), &temptail, 8); + if (err) { + if (err == LFS_ERR_CORRUPT) { + break; + } + return err; + } + lfs_pair_fromle32(temptail); + } else if (lfs_tag_type3(tag) == LFS_TYPE_FCRC) { + err = lfs_bd_read(lfs, + NULL, &lfs->rcache, lfs->cfg->block_size, + dir->pair[0], off+sizeof(tag), + &fcrc, sizeof(fcrc)); + if (err) { + if (err == LFS_ERR_CORRUPT) { + break; + } + } + + lfs_fcrc_fromle32(&fcrc); + hasfcrc = true; + } + + // found a match for our fetcher? + if ((fmask & tag) == (fmask & ftag)) { + int res = cb(data, tag, &(struct lfs_diskoff){ + dir->pair[0], off+sizeof(tag)}); + if (res < 0) { + if (res == LFS_ERR_CORRUPT) { + break; + } + return res; + } + + if (res == LFS_CMP_EQ) { + // found a match + tempbesttag = tag; + } else if ((LFS_MKTAG(0x7ff, 0x3ff, 0) & tag) == + (LFS_MKTAG(0x7ff, 0x3ff, 0) & tempbesttag)) { + // found an identical tag, but contents didn't match + // this must mean that our besttag has been overwritten + tempbesttag = -1; + } else if (res == LFS_CMP_GT && + lfs_tag_id(tag) <= lfs_tag_id(tempbesttag)) { + // found a greater match, keep track to keep things sorted + tempbesttag = tag | 0x80000000; + } + } + } + + // found no valid commits? + if (dir->off == 0) { + // try the other block? + lfs_pair_swap(dir->pair); + dir->rev = revs[(r+1)%2]; + continue; + } + + // did we end on a valid commit? we may have an erased block + dir->erased = false; + if (maybeerased && dir->off % lfs->cfg->prog_size == 0) { + #ifdef LFS_MULTIVERSION + // note versions < lfs2.1 did not have fcrc tags, if + // we're < lfs2.1 treat missing fcrc as erased data + // + // we don't strictly need to do this, but otherwise writing + // to lfs2.0 disks becomes very inefficient + if (lfs_fs_disk_version(lfs) < 0x00020001) { + dir->erased = true; + + } else + #endif + if (hasfcrc) { + // check for an fcrc matching the next prog's erased state, if + // this failed most likely a previous prog was interrupted, we + // need a new erase + uint32_t fcrc_ = 0xffffffff; + int err = lfs_bd_crc(lfs, + NULL, &lfs->rcache, lfs->cfg->block_size, + dir->pair[0], dir->off, fcrc.size, &fcrc_); + if (err && err != LFS_ERR_CORRUPT) { + return err; + } + + // found beginning of erased part? + dir->erased = (fcrc_ == fcrc.crc); + } + } + + // synthetic move + if (lfs_gstate_hasmovehere(&lfs->gdisk, dir->pair)) { + if (lfs_tag_id(lfs->gdisk.tag) == lfs_tag_id(besttag)) { + besttag |= 0x80000000; + } else if (besttag != -1 && + lfs_tag_id(lfs->gdisk.tag) < lfs_tag_id(besttag)) { + besttag -= LFS_MKTAG(0, 1, 0); + } + } + + // found tag? or found best id? + if (id) { + *id = lfs_min(lfs_tag_id(besttag), dir->count); + } + + if (lfs_tag_isvalid(besttag)) { + return besttag; + } else if (lfs_tag_id(besttag) < dir->count) { + return LFS_ERR_NOENT; + } else { + return 0; + } + } + + LFS_ERROR("Corrupted dir pair at {0x%"PRIx32", 0x%"PRIx32"}", + dir->pair[0], dir->pair[1]); + return LFS_ERR_CORRUPT; +} + +static int lfs_dir_fetch(lfs_t *lfs, + lfs_mdir_t *dir, const lfs_block_t pair[2]) { + // note, mask=-1, tag=-1 can never match a tag since this + // pattern has the invalid bit set + return (int)lfs_dir_fetchmatch(lfs, dir, pair, + (lfs_tag_t)-1, (lfs_tag_t)-1, NULL, NULL, NULL); +} + +static int lfs_dir_getgstate(lfs_t *lfs, const lfs_mdir_t *dir, + lfs_gstate_t *gstate) { + lfs_gstate_t temp; + lfs_stag_t res = lfs_dir_get(lfs, dir, LFS_MKTAG(0x7ff, 0, 0), + LFS_MKTAG(LFS_TYPE_MOVESTATE, 0, sizeof(temp)), &temp); + if (res < 0 && res != LFS_ERR_NOENT) { + return res; + } + + if (res != LFS_ERR_NOENT) { + // xor together to find resulting gstate + lfs_gstate_fromle32(&temp); + lfs_gstate_xor(gstate, &temp); + } + + return 0; +} + +static int lfs_dir_getinfo(lfs_t *lfs, lfs_mdir_t *dir, + uint16_t id, struct lfs_info *info) { + if (id == 0x3ff) { + // special case for root + strcpy(info->name, "/"); + info->type = LFS_TYPE_DIR; + return 0; + } + + lfs_stag_t tag = lfs_dir_get(lfs, dir, LFS_MKTAG(0x780, 0x3ff, 0), + LFS_MKTAG(LFS_TYPE_NAME, id, lfs->name_max+1), info->name); + if (tag < 0) { + return (int)tag; + } + + info->type = lfs_tag_type3(tag); + + struct lfs_ctz ctz; + tag = lfs_dir_get(lfs, dir, LFS_MKTAG(0x700, 0x3ff, 0), + LFS_MKTAG(LFS_TYPE_STRUCT, id, sizeof(ctz)), &ctz); + if (tag < 0) { + return (int)tag; + } + lfs_ctz_fromle32(&ctz); + + if (lfs_tag_type3(tag) == LFS_TYPE_CTZSTRUCT) { + info->size = ctz.size; + } else if (lfs_tag_type3(tag) == LFS_TYPE_INLINESTRUCT) { + info->size = lfs_tag_size(tag); + } + + return 0; +} + +struct lfs_dir_find_match { + lfs_t *lfs; + const void *name; + lfs_size_t size; +}; + +static int lfs_dir_find_match(void *data, + lfs_tag_t tag, const void *buffer) { + struct lfs_dir_find_match *name = data; + lfs_t *lfs = name->lfs; + const struct lfs_diskoff *disk = buffer; + + // compare with disk + lfs_size_t diff = lfs_min(name->size, lfs_tag_size(tag)); + int res = lfs_bd_cmp(lfs, + NULL, &lfs->rcache, diff, + disk->block, disk->off, name->name, diff); + if (res != LFS_CMP_EQ) { + return res; + } + + // only equal if our size is still the same + if (name->size != lfs_tag_size(tag)) { + return (name->size < lfs_tag_size(tag)) ? LFS_CMP_LT : LFS_CMP_GT; + } + + // found a match! + return LFS_CMP_EQ; +} + +static lfs_stag_t lfs_dir_find(lfs_t *lfs, lfs_mdir_t *dir, + const char **path, uint16_t *id) { + // we reduce path to a single name if we can find it + const char *name = *path; + if (id) { + *id = 0x3ff; + } + + // default to root dir + lfs_stag_t tag = LFS_MKTAG(LFS_TYPE_DIR, 0x3ff, 0); + dir->tail[0] = lfs->root[0]; + dir->tail[1] = lfs->root[1]; + + while (true) { +nextname: + // skip slashes + name += strspn(name, "/"); + lfs_size_t namelen = strcspn(name, "/"); + + // skip '.' and root '..' + if ((namelen == 1 && memcmp(name, ".", 1) == 0) || + (namelen == 2 && memcmp(name, "..", 2) == 0)) { + name += namelen; + goto nextname; + } + + // skip if matched by '..' in name + const char *suffix = name + namelen; + lfs_size_t sufflen; + int depth = 1; + while (true) { + suffix += strspn(suffix, "/"); + sufflen = strcspn(suffix, "/"); + if (sufflen == 0) { + break; + } + + if (sufflen == 2 && memcmp(suffix, "..", 2) == 0) { + depth -= 1; + if (depth == 0) { + name = suffix + sufflen; + goto nextname; + } + } else { + depth += 1; + } + + suffix += sufflen; + } + + // found path + if (name[0] == '\0') { + return tag; + } + + // update what we've found so far + *path = name; + + // only continue if we hit a directory + if (lfs_tag_type3(tag) != LFS_TYPE_DIR) { + return LFS_ERR_NOTDIR; + } + + // grab the entry data + if (lfs_tag_id(tag) != 0x3ff) { + lfs_stag_t res = lfs_dir_get(lfs, dir, LFS_MKTAG(0x700, 0x3ff, 0), + LFS_MKTAG(LFS_TYPE_STRUCT, lfs_tag_id(tag), 8), dir->tail); + if (res < 0) { + return res; + } + lfs_pair_fromle32(dir->tail); + } + + // find entry matching name + while (true) { + tag = lfs_dir_fetchmatch(lfs, dir, dir->tail, + LFS_MKTAG(0x780, 0, 0), + LFS_MKTAG(LFS_TYPE_NAME, 0, namelen), + // are we last name? + (strchr(name, '/') == NULL) ? id : NULL, + lfs_dir_find_match, &(struct lfs_dir_find_match){ + lfs, name, namelen}); + if (tag < 0) { + return tag; + } + + if (tag) { + break; + } + + if (!dir->split) { + return LFS_ERR_NOENT; + } + } + + // to next name + name += namelen; + } +} + +// commit logic +struct lfs_commit { + lfs_block_t block; + lfs_off_t off; + lfs_tag_t ptag; + uint32_t crc; + + lfs_off_t begin; + lfs_off_t end; +}; + +#ifndef LFS_READONLY +static int lfs_dir_commitprog(lfs_t *lfs, struct lfs_commit *commit, + const void *buffer, lfs_size_t size) { + int err = lfs_bd_prog(lfs, + &lfs->pcache, &lfs->rcache, false, + commit->block, commit->off , + (const uint8_t*)buffer, size); + if (err) { + return err; + } + + commit->crc = lfs_crc(commit->crc, buffer, size); + commit->off += size; + return 0; +} +#endif + +#ifndef LFS_READONLY +static int lfs_dir_commitattr(lfs_t *lfs, struct lfs_commit *commit, + lfs_tag_t tag, const void *buffer) { + // check if we fit + lfs_size_t dsize = lfs_tag_dsize(tag); + if (commit->off + dsize > commit->end) { + return LFS_ERR_NOSPC; + } + + // write out tag + lfs_tag_t ntag = lfs_tobe32((tag & 0x7fffffff) ^ commit->ptag); + int err = lfs_dir_commitprog(lfs, commit, &ntag, sizeof(ntag)); + if (err) { + return err; + } + + if (!(tag & 0x80000000)) { + // from memory + err = lfs_dir_commitprog(lfs, commit, buffer, dsize-sizeof(tag)); + if (err) { + return err; + } + } else { + // from disk + const struct lfs_diskoff *disk = buffer; + for (lfs_off_t i = 0; i < dsize-sizeof(tag); i++) { + // rely on caching to make this efficient + uint8_t dat; + err = lfs_bd_read(lfs, + NULL, &lfs->rcache, dsize-sizeof(tag)-i, + disk->block, disk->off+i, &dat, 1); + if (err) { + return err; + } + + err = lfs_dir_commitprog(lfs, commit, &dat, 1); + if (err) { + return err; + } + } + } + + commit->ptag = tag & 0x7fffffff; + return 0; +} +#endif + +#ifndef LFS_READONLY + +static int lfs_dir_commitcrc(lfs_t *lfs, struct lfs_commit *commit) { + // align to program units + // + // this gets a bit complex as we have two types of crcs: + // - 5-word crc with fcrc to check following prog (middle of block) + // - 2-word crc with no following prog (end of block) + const lfs_off_t end = lfs_alignup( + lfs_min(commit->off + 5*sizeof(uint32_t), lfs->cfg->block_size), + lfs->cfg->prog_size); + + lfs_off_t off1 = 0; + uint32_t crc1 = 0; + + // create crc tags to fill up remainder of commit, note that + // padding is not crced, which lets fetches skip padding but + // makes committing a bit more complicated + while (commit->off < end) { + lfs_off_t noff = ( + lfs_min(end - (commit->off+sizeof(lfs_tag_t)), 0x3fe) + + (commit->off+sizeof(lfs_tag_t))); + // too large for crc tag? need padding commits + if (noff < end) { + noff = lfs_min(noff, end - 5*sizeof(uint32_t)); + } + + // space for fcrc? + uint8_t eperturb = (uint8_t)-1; + if (noff >= end && noff <= lfs->cfg->block_size - lfs->cfg->prog_size) { + // first read the leading byte, this always contains a bit + // we can perturb to avoid writes that don't change the fcrc + int err = lfs_bd_read(lfs, + NULL, &lfs->rcache, lfs->cfg->prog_size, + commit->block, noff, &eperturb, 1); + if (err && err != LFS_ERR_CORRUPT) { + return err; + } + + #ifdef LFS_MULTIVERSION + // unfortunately fcrcs break mdir fetching < lfs2.1, so only write + // these if we're a >= lfs2.1 filesystem + if (lfs_fs_disk_version(lfs) <= 0x00020000) { + // don't write fcrc + } else + #endif + { + // find the expected fcrc, don't bother avoiding a reread + // of the eperturb, it should still be in our cache + struct lfs_fcrc fcrc = { + .size = lfs->cfg->prog_size, + .crc = 0xffffffff + }; + err = lfs_bd_crc(lfs, + NULL, &lfs->rcache, lfs->cfg->prog_size, + commit->block, noff, fcrc.size, &fcrc.crc); + if (err && err != LFS_ERR_CORRUPT) { + return err; + } + + lfs_fcrc_tole32(&fcrc); + err = lfs_dir_commitattr(lfs, commit, + LFS_MKTAG(LFS_TYPE_FCRC, 0x3ff, sizeof(struct lfs_fcrc)), + &fcrc); + if (err) { + return err; + } + } + } + + // build commit crc + struct { + lfs_tag_t tag; + uint32_t crc; + } ccrc; + lfs_tag_t ntag = LFS_MKTAG( + LFS_TYPE_CCRC + (((uint8_t)~eperturb) >> 7), 0x3ff, + noff - (commit->off+sizeof(lfs_tag_t))); + ccrc.tag = lfs_tobe32(ntag ^ commit->ptag); + commit->crc = lfs_crc(commit->crc, &ccrc.tag, sizeof(lfs_tag_t)); + ccrc.crc = lfs_tole32(commit->crc); + + int err = lfs_bd_prog(lfs, + &lfs->pcache, &lfs->rcache, false, + commit->block, commit->off, &ccrc, sizeof(ccrc)); + if (err) { + return err; + } + + // keep track of non-padding checksum to verify + if (off1 == 0) { + off1 = commit->off + sizeof(lfs_tag_t); + crc1 = commit->crc; + } + + commit->off = noff; + // perturb valid bit? + commit->ptag = ntag ^ ((0x80UL & ~eperturb) << 24); + // reset crc for next commit + commit->crc = 0xffffffff; + + // manually flush here since we don't prog the padding, this confuses + // the caching layer + if (noff >= end || noff >= lfs->pcache.off + lfs->cfg->cache_size) { + // flush buffers + int err = lfs_bd_sync(lfs, &lfs->pcache, &lfs->rcache, false); + if (err) { + return err; + } + } + } + + // successful commit, check checksums to make sure + // + // note that we don't need to check padding commits, worst + // case if they are corrupted we would have had to compact anyways + lfs_off_t off = commit->begin; + uint32_t crc = 0xffffffff; + int err = lfs_bd_crc(lfs, + NULL, &lfs->rcache, off1+sizeof(uint32_t), + commit->block, off, off1-off, &crc); + if (err) { + return err; + } + + // check non-padding commits against known crc + if (crc != crc1) { + return LFS_ERR_CORRUPT; + } + + // make sure to check crc in case we happen to pick + // up an unrelated crc (frozen block?) + err = lfs_bd_crc(lfs, + NULL, &lfs->rcache, sizeof(uint32_t), + commit->block, off1, sizeof(uint32_t), &crc); + if (err) { + return err; + } + + if (crc != 0) { + return LFS_ERR_CORRUPT; + } + + return 0; +} +#endif + +#ifndef LFS_READONLY +static int lfs_dir_alloc(lfs_t *lfs, lfs_mdir_t *dir) { + // allocate pair of dir blocks (backwards, so we write block 1 first) + for (int i = 0; i < 2; i++) { + int err = lfs_alloc(lfs, &dir->pair[(i+1)%2]); + if (err) { + return err; + } + } + + // zero for reproducibility in case initial block is unreadable + dir->rev = 0; + + // rather than clobbering one of the blocks we just pretend + // the revision may be valid + int err = lfs_bd_read(lfs, + NULL, &lfs->rcache, sizeof(dir->rev), + dir->pair[0], 0, &dir->rev, sizeof(dir->rev)); + dir->rev = lfs_fromle32(dir->rev); + if (err && err != LFS_ERR_CORRUPT) { + return err; + } + + // to make sure we don't immediately evict, align the new revision count + // to our block_cycles modulus, see lfs_dir_compact for why our modulus + // is tweaked this way + if (lfs->cfg->block_cycles > 0) { + dir->rev = lfs_alignup(dir->rev, ((lfs->cfg->block_cycles+1)|1)); + } + + // set defaults + dir->off = sizeof(dir->rev); + dir->etag = 0xffffffff; + dir->count = 0; + dir->tail[0] = LFS_BLOCK_NULL; + dir->tail[1] = LFS_BLOCK_NULL; + dir->erased = false; + dir->split = false; + + // don't write out yet, let caller take care of that + return 0; +} +#endif + +#ifndef LFS_READONLY +static int lfs_dir_drop(lfs_t *lfs, lfs_mdir_t *dir, lfs_mdir_t *tail) { + // steal state + int err = lfs_dir_getgstate(lfs, tail, &lfs->gdelta); + if (err) { + return err; + } + + // steal tail + lfs_pair_tole32(tail->tail); + err = lfs_dir_commit(lfs, dir, LFS_MKATTRS( + {LFS_MKTAG(LFS_TYPE_TAIL + tail->split, 0x3ff, 8), tail->tail})); + lfs_pair_fromle32(tail->tail); + if (err) { + return err; + } + + return 0; +} +#endif + +#ifndef LFS_READONLY +static int lfs_dir_split(lfs_t *lfs, + lfs_mdir_t *dir, const struct lfs_mattr *attrs, int attrcount, + lfs_mdir_t *source, uint16_t split, uint16_t end) { + // create tail metadata pair + lfs_mdir_t tail; + int err = lfs_dir_alloc(lfs, &tail); + if (err) { + return err; + } + + tail.split = dir->split; + tail.tail[0] = dir->tail[0]; + tail.tail[1] = dir->tail[1]; + + // note we don't care about LFS_OK_RELOCATED + int res = lfs_dir_compact(lfs, &tail, attrs, attrcount, source, split, end); + if (res < 0) { + return res; + } + + dir->tail[0] = tail.pair[0]; + dir->tail[1] = tail.pair[1]; + dir->split = true; + + // update root if needed + if (lfs_pair_cmp(dir->pair, lfs->root) == 0 && split == 0) { + lfs->root[0] = tail.pair[0]; + lfs->root[1] = tail.pair[1]; + } + + return 0; +} +#endif + +#ifndef LFS_READONLY +static int lfs_dir_commit_size(void *p, lfs_tag_t tag, const void *buffer) { + lfs_size_t *size = p; + (void)buffer; + + *size += lfs_tag_dsize(tag); + return 0; +} +#endif + +#ifndef LFS_READONLY +struct lfs_dir_commit_commit { + lfs_t *lfs; + struct lfs_commit *commit; +}; +#endif + +#ifndef LFS_READONLY +static int lfs_dir_commit_commit(void *p, lfs_tag_t tag, const void *buffer) { + struct lfs_dir_commit_commit *commit = p; + return lfs_dir_commitattr(commit->lfs, commit->commit, tag, buffer); +} +#endif + +#ifndef LFS_READONLY +static bool lfs_dir_needsrelocation(lfs_t *lfs, lfs_mdir_t *dir) { + // If our revision count == n * block_cycles, we should force a relocation, + // this is how littlefs wear-levels at the metadata-pair level. Note that we + // actually use (block_cycles+1)|1, this is to avoid two corner cases: + // 1. block_cycles = 1, which would prevent relocations from terminating + // 2. block_cycles = 2n, which, due to aliasing, would only ever relocate + // one metadata block in the pair, effectively making this useless + return (lfs->cfg->block_cycles > 0 + && ((dir->rev + 1) % ((lfs->cfg->block_cycles+1)|1) == 0)); +} +#endif + +#ifndef LFS_READONLY +static int lfs_dir_compact(lfs_t *lfs, + lfs_mdir_t *dir, const struct lfs_mattr *attrs, int attrcount, + lfs_mdir_t *source, uint16_t begin, uint16_t end) { + // save some state in case block is bad + bool relocated = false; + bool tired = lfs_dir_needsrelocation(lfs, dir); + + // increment revision count + dir->rev += 1; + + // do not proactively relocate blocks during migrations, this + // can cause a number of failure states such: clobbering the + // v1 superblock if we relocate root, and invalidating directory + // pointers if we relocate the head of a directory. On top of + // this, relocations increase the overall complexity of + // lfs_migration, which is already a delicate operation. +#ifdef LFS_MIGRATE + if (lfs->lfs1) { + tired = false; + } +#endif + + if (tired && lfs_pair_cmp(dir->pair, (const lfs_block_t[2]){0, 1}) != 0) { + // we're writing too much, time to relocate + goto relocate; + } + + // begin loop to commit compaction to blocks until a compact sticks + while (true) { + { + // setup commit state + struct lfs_commit commit = { + .block = dir->pair[1], + .off = 0, + .ptag = 0xffffffff, + .crc = 0xffffffff, + + .begin = 0, + .end = (lfs->cfg->metadata_max ? + lfs->cfg->metadata_max : lfs->cfg->block_size) - 8, + }; + + // erase block to write to + int err = lfs_bd_erase(lfs, dir->pair[1]); + if (err) { + if (err == LFS_ERR_CORRUPT) { + goto relocate; + } + return err; + } + + // write out header + dir->rev = lfs_tole32(dir->rev); + err = lfs_dir_commitprog(lfs, &commit, + &dir->rev, sizeof(dir->rev)); + dir->rev = lfs_fromle32(dir->rev); + if (err) { + if (err == LFS_ERR_CORRUPT) { + goto relocate; + } + return err; + } + + // traverse the directory, this time writing out all unique tags + err = lfs_dir_traverse(lfs, + source, 0, 0xffffffff, attrs, attrcount, + LFS_MKTAG(0x400, 0x3ff, 0), + LFS_MKTAG(LFS_TYPE_NAME, 0, 0), + begin, end, -begin, + lfs_dir_commit_commit, &(struct lfs_dir_commit_commit){ + lfs, &commit}); + if (err) { + if (err == LFS_ERR_CORRUPT) { + goto relocate; + } + return err; + } + + // commit tail, which may be new after last size check + if (!lfs_pair_isnull(dir->tail)) { + lfs_pair_tole32(dir->tail); + err = lfs_dir_commitattr(lfs, &commit, + LFS_MKTAG(LFS_TYPE_TAIL + dir->split, 0x3ff, 8), + dir->tail); + lfs_pair_fromle32(dir->tail); + if (err) { + if (err == LFS_ERR_CORRUPT) { + goto relocate; + } + return err; + } + } + + // bring over gstate? + lfs_gstate_t delta = {0}; + if (!relocated) { + lfs_gstate_xor(&delta, &lfs->gdisk); + lfs_gstate_xor(&delta, &lfs->gstate); + } + lfs_gstate_xor(&delta, &lfs->gdelta); + delta.tag &= ~LFS_MKTAG(0, 0, 0x3ff); + + err = lfs_dir_getgstate(lfs, dir, &delta); + if (err) { + return err; + } + + if (!lfs_gstate_iszero(&delta)) { + lfs_gstate_tole32(&delta); + err = lfs_dir_commitattr(lfs, &commit, + LFS_MKTAG(LFS_TYPE_MOVESTATE, 0x3ff, + sizeof(delta)), &delta); + if (err) { + if (err == LFS_ERR_CORRUPT) { + goto relocate; + } + return err; + } + } + + // complete commit with crc + err = lfs_dir_commitcrc(lfs, &commit); + if (err) { + if (err == LFS_ERR_CORRUPT) { + goto relocate; + } + return err; + } + + // successful compaction, swap dir pair to indicate most recent + LFS_ASSERT(commit.off % lfs->cfg->prog_size == 0); + lfs_pair_swap(dir->pair); + dir->count = end - begin; + dir->off = commit.off; + dir->etag = commit.ptag; + // update gstate + lfs->gdelta = (lfs_gstate_t){0}; + if (!relocated) { + lfs->gdisk = lfs->gstate; + } + } + break; + +relocate: + // commit was corrupted, drop caches and prepare to relocate block + relocated = true; + lfs_cache_drop(lfs, &lfs->pcache); + if (!tired) { + LFS_DEBUG("Bad block at 0x%"PRIx32, dir->pair[1]); + } + + // can't relocate superblock, filesystem is now frozen + if (lfs_pair_cmp(dir->pair, (const lfs_block_t[2]){0, 1}) == 0) { + LFS_WARN("Superblock 0x%"PRIx32" has become unwritable", + dir->pair[1]); + return LFS_ERR_NOSPC; + } + + // relocate half of pair + int err = lfs_alloc(lfs, &dir->pair[1]); + if (err && (err != LFS_ERR_NOSPC || !tired)) { + return err; + } + + tired = false; + continue; + } + + return relocated ? LFS_OK_RELOCATED : 0; +} +#endif + +#ifndef LFS_READONLY +static int lfs_dir_splittingcompact(lfs_t *lfs, lfs_mdir_t *dir, + const struct lfs_mattr *attrs, int attrcount, + lfs_mdir_t *source, uint16_t begin, uint16_t end) { + while (true) { + // find size of first split, we do this by halving the split until + // the metadata is guaranteed to fit + // + // Note that this isn't a true binary search, we never increase the + // split size. This may result in poorly distributed metadata but isn't + // worth the extra code size or performance hit to fix. + lfs_size_t split = begin; + while (end - split > 1) { + lfs_size_t size = 0; + int err = lfs_dir_traverse(lfs, + source, 0, 0xffffffff, attrs, attrcount, + LFS_MKTAG(0x400, 0x3ff, 0), + LFS_MKTAG(LFS_TYPE_NAME, 0, 0), + split, end, -split, + lfs_dir_commit_size, &size); + if (err) { + return err; + } + + // space is complicated, we need room for: + // + // - tail: 4+2*4 = 12 bytes + // - gstate: 4+3*4 = 16 bytes + // - move delete: 4 = 4 bytes + // - crc: 4+4 = 8 bytes + // total = 40 bytes + // + // And we cap at half a block to avoid degenerate cases with + // nearly-full metadata blocks. + // + if (end - split < 0xff + && size <= lfs_min( + lfs->cfg->block_size - 40, + lfs_alignup( + (lfs->cfg->metadata_max + ? lfs->cfg->metadata_max + : lfs->cfg->block_size)/2, + lfs->cfg->prog_size))) { + break; + } + + split = split + ((end - split) / 2); + } + + if (split == begin) { + // no split needed + break; + } + + // split into two metadata pairs and continue + int err = lfs_dir_split(lfs, dir, attrs, attrcount, + source, split, end); + if (err && err != LFS_ERR_NOSPC) { + return err; + } + + if (err) { + // we can't allocate a new block, try to compact with degraded + // performance + LFS_WARN("Unable to split {0x%"PRIx32", 0x%"PRIx32"}", + dir->pair[0], dir->pair[1]); + break; + } else { + end = split; + } + } + + if (lfs_dir_needsrelocation(lfs, dir) + && lfs_pair_cmp(dir->pair, (const lfs_block_t[2]){0, 1}) == 0) { + // oh no! we're writing too much to the superblock, + // should we expand? + lfs_ssize_t size = lfs_fs_size_(lfs); + if (size < 0) { + return size; + } + + // littlefs cannot reclaim expanded superblocks, so expand cautiously + // + // if our filesystem is more than ~88% full, don't expand, this is + // somewhat arbitrary + if (lfs->block_count - size > lfs->block_count/8) { + LFS_DEBUG("Expanding superblock at rev %"PRIu32, dir->rev); + int err = lfs_dir_split(lfs, dir, attrs, attrcount, + source, begin, end); + if (err && err != LFS_ERR_NOSPC) { + return err; + } + + if (err) { + // welp, we tried, if we ran out of space there's not much + // we can do, we'll error later if we've become frozen + LFS_WARN("Unable to expand superblock"); + } else { + end = begin; + } + } + } + + return lfs_dir_compact(lfs, dir, attrs, attrcount, source, begin, end); +} +#endif + +#ifndef LFS_READONLY +static int lfs_dir_relocatingcommit(lfs_t *lfs, lfs_mdir_t *dir, + const lfs_block_t pair[2], + const struct lfs_mattr *attrs, int attrcount, + lfs_mdir_t *pdir) { + int state = 0; + + // calculate changes to the directory + bool hasdelete = false; + for (int i = 0; i < attrcount; i++) { + if (lfs_tag_type3(attrs[i].tag) == LFS_TYPE_CREATE) { + dir->count += 1; + } else if (lfs_tag_type3(attrs[i].tag) == LFS_TYPE_DELETE) { + LFS_ASSERT(dir->count > 0); + dir->count -= 1; + hasdelete = true; + } else if (lfs_tag_type1(attrs[i].tag) == LFS_TYPE_TAIL) { + dir->tail[0] = ((lfs_block_t*)attrs[i].buffer)[0]; + dir->tail[1] = ((lfs_block_t*)attrs[i].buffer)[1]; + dir->split = (lfs_tag_chunk(attrs[i].tag) & 1); + lfs_pair_fromle32(dir->tail); + } + } + + // should we actually drop the directory block? + if (hasdelete && dir->count == 0) { + LFS_ASSERT(pdir); + int err = lfs_fs_pred(lfs, dir->pair, pdir); + if (err && err != LFS_ERR_NOENT) { + return err; + } + + if (err != LFS_ERR_NOENT && pdir->split) { + state = LFS_OK_DROPPED; + goto fixmlist; + } + } + + if (dir->erased) { + // try to commit + struct lfs_commit commit = { + .block = dir->pair[0], + .off = dir->off, + .ptag = dir->etag, + .crc = 0xffffffff, + + .begin = dir->off, + .end = (lfs->cfg->metadata_max ? + lfs->cfg->metadata_max : lfs->cfg->block_size) - 8, + }; + + // traverse attrs that need to be written out + lfs_pair_tole32(dir->tail); + int err = lfs_dir_traverse(lfs, + dir, dir->off, dir->etag, attrs, attrcount, + 0, 0, 0, 0, 0, + lfs_dir_commit_commit, &(struct lfs_dir_commit_commit){ + lfs, &commit}); + lfs_pair_fromle32(dir->tail); + if (err) { + if (err == LFS_ERR_NOSPC || err == LFS_ERR_CORRUPT) { + goto compact; + } + return err; + } + + // commit any global diffs if we have any + lfs_gstate_t delta = {0}; + lfs_gstate_xor(&delta, &lfs->gstate); + lfs_gstate_xor(&delta, &lfs->gdisk); + lfs_gstate_xor(&delta, &lfs->gdelta); + delta.tag &= ~LFS_MKTAG(0, 0, 0x3ff); + if (!lfs_gstate_iszero(&delta)) { + err = lfs_dir_getgstate(lfs, dir, &delta); + if (err) { + return err; + } + + lfs_gstate_tole32(&delta); + err = lfs_dir_commitattr(lfs, &commit, + LFS_MKTAG(LFS_TYPE_MOVESTATE, 0x3ff, + sizeof(delta)), &delta); + if (err) { + if (err == LFS_ERR_NOSPC || err == LFS_ERR_CORRUPT) { + goto compact; + } + return err; + } + } + + // finalize commit with the crc + err = lfs_dir_commitcrc(lfs, &commit); + if (err) { + if (err == LFS_ERR_NOSPC || err == LFS_ERR_CORRUPT) { + goto compact; + } + return err; + } + + // successful commit, update dir + LFS_ASSERT(commit.off % lfs->cfg->prog_size == 0); + dir->off = commit.off; + dir->etag = commit.ptag; + // and update gstate + lfs->gdisk = lfs->gstate; + lfs->gdelta = (lfs_gstate_t){0}; + + goto fixmlist; + } + +compact: + // fall back to compaction + lfs_cache_drop(lfs, &lfs->pcache); + + state = lfs_dir_splittingcompact(lfs, dir, attrs, attrcount, + dir, 0, dir->count); + if (state < 0) { + return state; + } + + goto fixmlist; + +fixmlist:; + // this complicated bit of logic is for fixing up any active + // metadata-pairs that we may have affected + // + // note we have to make two passes since the mdir passed to + // lfs_dir_commit could also be in this list, and even then + // we need to copy the pair so they don't get clobbered if we refetch + // our mdir. + lfs_block_t oldpair[2] = {pair[0], pair[1]}; + for (struct lfs_mlist *d = lfs->mlist; d; d = d->next) { + if (lfs_pair_cmp(d->m.pair, oldpair) == 0) { + d->m = *dir; + if (d->m.pair != pair) { + for (int i = 0; i < attrcount; i++) { + if (lfs_tag_type3(attrs[i].tag) == LFS_TYPE_DELETE && + d->id == lfs_tag_id(attrs[i].tag)) { + d->m.pair[0] = LFS_BLOCK_NULL; + d->m.pair[1] = LFS_BLOCK_NULL; + } else if (lfs_tag_type3(attrs[i].tag) == LFS_TYPE_DELETE && + d->id > lfs_tag_id(attrs[i].tag)) { + d->id -= 1; + if (d->type == LFS_TYPE_DIR) { + ((lfs_dir_t*)d)->pos -= 1; + } + } else if (lfs_tag_type3(attrs[i].tag) == LFS_TYPE_CREATE && + d->id >= lfs_tag_id(attrs[i].tag)) { + d->id += 1; + if (d->type == LFS_TYPE_DIR) { + ((lfs_dir_t*)d)->pos += 1; + } + } + } + } + + while (d->id >= d->m.count && d->m.split) { + // we split and id is on tail now + d->id -= d->m.count; + int err = lfs_dir_fetch(lfs, &d->m, d->m.tail); + if (err) { + return err; + } + } + } + } + + return state; +} +#endif + +#ifndef LFS_READONLY +static int lfs_dir_orphaningcommit(lfs_t *lfs, lfs_mdir_t *dir, + const struct lfs_mattr *attrs, int attrcount) { + // check for any inline files that aren't RAM backed and + // forcefully evict them, needed for filesystem consistency + for (lfs_file_t *f = (lfs_file_t*)lfs->mlist; f; f = f->next) { + if (dir != &f->m && lfs_pair_cmp(f->m.pair, dir->pair) == 0 && + f->type == LFS_TYPE_REG && (f->flags & LFS_F_INLINE) && + f->ctz.size > lfs->cfg->cache_size) { + int err = lfs_file_outline(lfs, f); + if (err) { + return err; + } + + err = lfs_file_flush(lfs, f); + if (err) { + return err; + } + } + } + + lfs_block_t lpair[2] = {dir->pair[0], dir->pair[1]}; + lfs_mdir_t ldir = *dir; + lfs_mdir_t pdir; + int state = lfs_dir_relocatingcommit(lfs, &ldir, dir->pair, + attrs, attrcount, &pdir); + if (state < 0) { + return state; + } + + // update if we're not in mlist, note we may have already been + // updated if we are in mlist + if (lfs_pair_cmp(dir->pair, lpair) == 0) { + *dir = ldir; + } + + // commit was successful, but may require other changes in the + // filesystem, these would normally be tail recursive, but we have + // flattened them here avoid unbounded stack usage + + // need to drop? + if (state == LFS_OK_DROPPED) { + // steal state + int err = lfs_dir_getgstate(lfs, dir, &lfs->gdelta); + if (err) { + return err; + } + + // steal tail, note that this can't create a recursive drop + lpair[0] = pdir.pair[0]; + lpair[1] = pdir.pair[1]; + lfs_pair_tole32(dir->tail); + state = lfs_dir_relocatingcommit(lfs, &pdir, lpair, LFS_MKATTRS( + {LFS_MKTAG(LFS_TYPE_TAIL + dir->split, 0x3ff, 8), + dir->tail}), + NULL); + lfs_pair_fromle32(dir->tail); + if (state < 0) { + return state; + } + + ldir = pdir; + } + + // need to relocate? + bool orphans = false; + while (state == LFS_OK_RELOCATED) { + LFS_DEBUG("Relocating {0x%"PRIx32", 0x%"PRIx32"} " + "-> {0x%"PRIx32", 0x%"PRIx32"}", + lpair[0], lpair[1], ldir.pair[0], ldir.pair[1]); + state = 0; + + // update internal root + if (lfs_pair_cmp(lpair, lfs->root) == 0) { + lfs->root[0] = ldir.pair[0]; + lfs->root[1] = ldir.pair[1]; + } + + // update internally tracked dirs + for (struct lfs_mlist *d = lfs->mlist; d; d = d->next) { + if (lfs_pair_cmp(lpair, d->m.pair) == 0) { + d->m.pair[0] = ldir.pair[0]; + d->m.pair[1] = ldir.pair[1]; + } + + if (d->type == LFS_TYPE_DIR && + lfs_pair_cmp(lpair, ((lfs_dir_t*)d)->head) == 0) { + ((lfs_dir_t*)d)->head[0] = ldir.pair[0]; + ((lfs_dir_t*)d)->head[1] = ldir.pair[1]; + } + } + + // find parent + lfs_stag_t tag = lfs_fs_parent(lfs, lpair, &pdir); + if (tag < 0 && tag != LFS_ERR_NOENT) { + return tag; + } + + bool hasparent = (tag != LFS_ERR_NOENT); + if (tag != LFS_ERR_NOENT) { + // note that if we have a parent, we must have a pred, so this will + // always create an orphan + int err = lfs_fs_preporphans(lfs, +1); + if (err) { + return err; + } + + // fix pending move in this pair? this looks like an optimization but + // is in fact _required_ since relocating may outdate the move. + uint16_t moveid = 0x3ff; + if (lfs_gstate_hasmovehere(&lfs->gstate, pdir.pair)) { + moveid = lfs_tag_id(lfs->gstate.tag); + LFS_DEBUG("Fixing move while relocating " + "{0x%"PRIx32", 0x%"PRIx32"} 0x%"PRIx16"\n", + pdir.pair[0], pdir.pair[1], moveid); + lfs_fs_prepmove(lfs, 0x3ff, NULL); + if (moveid < lfs_tag_id(tag)) { + tag -= LFS_MKTAG(0, 1, 0); + } + } + + lfs_block_t ppair[2] = {pdir.pair[0], pdir.pair[1]}; + lfs_pair_tole32(ldir.pair); + state = lfs_dir_relocatingcommit(lfs, &pdir, ppair, LFS_MKATTRS( + {LFS_MKTAG_IF(moveid != 0x3ff, + LFS_TYPE_DELETE, moveid, 0), NULL}, + {tag, ldir.pair}), + NULL); + lfs_pair_fromle32(ldir.pair); + if (state < 0) { + return state; + } + + if (state == LFS_OK_RELOCATED) { + lpair[0] = ppair[0]; + lpair[1] = ppair[1]; + ldir = pdir; + orphans = true; + continue; + } + } + + // find pred + int err = lfs_fs_pred(lfs, lpair, &pdir); + if (err && err != LFS_ERR_NOENT) { + return err; + } + LFS_ASSERT(!(hasparent && err == LFS_ERR_NOENT)); + + // if we can't find dir, it must be new + if (err != LFS_ERR_NOENT) { + if (lfs_gstate_hasorphans(&lfs->gstate)) { + // next step, clean up orphans + err = lfs_fs_preporphans(lfs, -hasparent); + if (err) { + return err; + } + } + + // fix pending move in this pair? this looks like an optimization + // but is in fact _required_ since relocating may outdate the move. + uint16_t moveid = 0x3ff; + if (lfs_gstate_hasmovehere(&lfs->gstate, pdir.pair)) { + moveid = lfs_tag_id(lfs->gstate.tag); + LFS_DEBUG("Fixing move while relocating " + "{0x%"PRIx32", 0x%"PRIx32"} 0x%"PRIx16"\n", + pdir.pair[0], pdir.pair[1], moveid); + lfs_fs_prepmove(lfs, 0x3ff, NULL); + } + + // replace bad pair, either we clean up desync, or no desync occured + lpair[0] = pdir.pair[0]; + lpair[1] = pdir.pair[1]; + lfs_pair_tole32(ldir.pair); + state = lfs_dir_relocatingcommit(lfs, &pdir, lpair, LFS_MKATTRS( + {LFS_MKTAG_IF(moveid != 0x3ff, + LFS_TYPE_DELETE, moveid, 0), NULL}, + {LFS_MKTAG(LFS_TYPE_TAIL + pdir.split, 0x3ff, 8), + ldir.pair}), + NULL); + lfs_pair_fromle32(ldir.pair); + if (state < 0) { + return state; + } + + ldir = pdir; + } + } + + return orphans ? LFS_OK_ORPHANED : 0; +} +#endif + +#ifndef LFS_READONLY +static int lfs_dir_commit(lfs_t *lfs, lfs_mdir_t *dir, + const struct lfs_mattr *attrs, int attrcount) { + int orphans = lfs_dir_orphaningcommit(lfs, dir, attrs, attrcount); + if (orphans < 0) { + return orphans; + } + + if (orphans) { + // make sure we've removed all orphans, this is a noop if there + // are none, but if we had nested blocks failures we may have + // created some + int err = lfs_fs_deorphan(lfs, false); + if (err) { + return err; + } + } + + return 0; +} +#endif + + +/// Top level directory operations /// +#ifndef LFS_READONLY +static int lfs_mkdir_(lfs_t *lfs, const char *path) { + // deorphan if we haven't yet, needed at most once after poweron + int err = lfs_fs_forceconsistency(lfs); + if (err) { + return err; + } + + struct lfs_mlist cwd; + cwd.next = lfs->mlist; + uint16_t id; + err = lfs_dir_find(lfs, &cwd.m, &path, &id); + if (!(err == LFS_ERR_NOENT && id != 0x3ff)) { + return (err < 0) ? err : LFS_ERR_EXIST; + } + + // check that name fits + lfs_size_t nlen = strlen(path); + if (nlen > lfs->name_max) { + return LFS_ERR_NAMETOOLONG; + } + + // build up new directory + lfs_alloc_ckpoint(lfs); + lfs_mdir_t dir; + err = lfs_dir_alloc(lfs, &dir); + if (err) { + return err; + } + + // find end of list + lfs_mdir_t pred = cwd.m; + while (pred.split) { + err = lfs_dir_fetch(lfs, &pred, pred.tail); + if (err) { + return err; + } + } + + // setup dir + lfs_pair_tole32(pred.tail); + err = lfs_dir_commit(lfs, &dir, LFS_MKATTRS( + {LFS_MKTAG(LFS_TYPE_SOFTTAIL, 0x3ff, 8), pred.tail})); + lfs_pair_fromle32(pred.tail); + if (err) { + return err; + } + + // current block not end of list? + if (cwd.m.split) { + // update tails, this creates a desync + err = lfs_fs_preporphans(lfs, +1); + if (err) { + return err; + } + + // it's possible our predecessor has to be relocated, and if + // our parent is our predecessor's predecessor, this could have + // caused our parent to go out of date, fortunately we can hook + // ourselves into littlefs to catch this + cwd.type = 0; + cwd.id = 0; + lfs->mlist = &cwd; + + lfs_pair_tole32(dir.pair); + err = lfs_dir_commit(lfs, &pred, LFS_MKATTRS( + {LFS_MKTAG(LFS_TYPE_SOFTTAIL, 0x3ff, 8), dir.pair})); + lfs_pair_fromle32(dir.pair); + if (err) { + lfs->mlist = cwd.next; + return err; + } + + lfs->mlist = cwd.next; + err = lfs_fs_preporphans(lfs, -1); + if (err) { + return err; + } + } + + // now insert into our parent block + lfs_pair_tole32(dir.pair); + err = lfs_dir_commit(lfs, &cwd.m, LFS_MKATTRS( + {LFS_MKTAG(LFS_TYPE_CREATE, id, 0), NULL}, + {LFS_MKTAG(LFS_TYPE_DIR, id, nlen), path}, + {LFS_MKTAG(LFS_TYPE_DIRSTRUCT, id, 8), dir.pair}, + {LFS_MKTAG_IF(!cwd.m.split, + LFS_TYPE_SOFTTAIL, 0x3ff, 8), dir.pair})); + lfs_pair_fromle32(dir.pair); + if (err) { + return err; + } + + return 0; +} +#endif + +static int lfs_dir_open_(lfs_t *lfs, lfs_dir_t *dir, const char *path) { + lfs_stag_t tag = lfs_dir_find(lfs, &dir->m, &path, NULL); + if (tag < 0) { + return tag; + } + + if (lfs_tag_type3(tag) != LFS_TYPE_DIR) { + return LFS_ERR_NOTDIR; + } + + lfs_block_t pair[2]; + if (lfs_tag_id(tag) == 0x3ff) { + // handle root dir separately + pair[0] = lfs->root[0]; + pair[1] = lfs->root[1]; + } else { + // get dir pair from parent + lfs_stag_t res = lfs_dir_get(lfs, &dir->m, LFS_MKTAG(0x700, 0x3ff, 0), + LFS_MKTAG(LFS_TYPE_STRUCT, lfs_tag_id(tag), 8), pair); + if (res < 0) { + return res; + } + lfs_pair_fromle32(pair); + } + + // fetch first pair + int err = lfs_dir_fetch(lfs, &dir->m, pair); + if (err) { + return err; + } + + // setup entry + dir->head[0] = dir->m.pair[0]; + dir->head[1] = dir->m.pair[1]; + dir->id = 0; + dir->pos = 0; + + // add to list of mdirs + dir->type = LFS_TYPE_DIR; + lfs_mlist_append(lfs, (struct lfs_mlist *)dir); + + return 0; +} + +static int lfs_dir_close_(lfs_t *lfs, lfs_dir_t *dir) { + // remove from list of mdirs + lfs_mlist_remove(lfs, (struct lfs_mlist *)dir); + + return 0; +} + +static int lfs_dir_read_(lfs_t *lfs, lfs_dir_t *dir, struct lfs_info *info) { + memset(info, 0, sizeof(*info)); + + // special offset for '.' and '..' + if (dir->pos == 0) { + info->type = LFS_TYPE_DIR; + strcpy(info->name, "."); + dir->pos += 1; + return true; + } else if (dir->pos == 1) { + info->type = LFS_TYPE_DIR; + strcpy(info->name, ".."); + dir->pos += 1; + return true; + } + + while (true) { + if (dir->id == dir->m.count) { + if (!dir->m.split) { + return false; + } + + int err = lfs_dir_fetch(lfs, &dir->m, dir->m.tail); + if (err) { + return err; + } + + dir->id = 0; + } + + int err = lfs_dir_getinfo(lfs, &dir->m, dir->id, info); + if (err && err != LFS_ERR_NOENT) { + return err; + } + + dir->id += 1; + if (err != LFS_ERR_NOENT) { + break; + } + } + + dir->pos += 1; + return true; +} + +static int lfs_dir_seek_(lfs_t *lfs, lfs_dir_t *dir, lfs_off_t off) { + // simply walk from head dir + int err = lfs_dir_rewind_(lfs, dir); + if (err) { + return err; + } + + // first two for ./.. + dir->pos = lfs_min(2, off); + off -= dir->pos; + + // skip superblock entry + dir->id = (off > 0 && lfs_pair_cmp(dir->head, lfs->root) == 0); + + while (off > 0) { + if (dir->id == dir->m.count) { + if (!dir->m.split) { + return LFS_ERR_INVAL; + } + + err = lfs_dir_fetch(lfs, &dir->m, dir->m.tail); + if (err) { + return err; + } + + dir->id = 0; + } + + int diff = lfs_min(dir->m.count - dir->id, off); + dir->id += diff; + dir->pos += diff; + off -= diff; + } + + return 0; +} + +static lfs_soff_t lfs_dir_tell_(lfs_t *lfs, lfs_dir_t *dir) { + (void)lfs; + return dir->pos; +} + +static int lfs_dir_rewind_(lfs_t *lfs, lfs_dir_t *dir) { + // reload the head dir + int err = lfs_dir_fetch(lfs, &dir->m, dir->head); + if (err) { + return err; + } + + dir->id = 0; + dir->pos = 0; + return 0; +} + + +/// File index list operations /// +static int lfs_ctz_index(lfs_t *lfs, lfs_off_t *off) { + lfs_off_t size = *off; + lfs_off_t b = lfs->cfg->block_size - 2*4; + lfs_off_t i = size / b; + if (i == 0) { + return 0; + } + + i = (size - 4*(lfs_popc(i-1)+2)) / b; + *off = size - b*i - 4*lfs_popc(i); + return i; +} + +static int lfs_ctz_find(lfs_t *lfs, + const lfs_cache_t *pcache, lfs_cache_t *rcache, + lfs_block_t head, lfs_size_t size, + lfs_size_t pos, lfs_block_t *block, lfs_off_t *off) { + if (size == 0) { + *block = LFS_BLOCK_NULL; + *off = 0; + return 0; + } + + lfs_off_t current = lfs_ctz_index(lfs, &(lfs_off_t){size-1}); + lfs_off_t target = lfs_ctz_index(lfs, &pos); + + while (current > target) { + lfs_size_t skip = lfs_min( + lfs_npw2(current-target+1) - 1, + lfs_ctz(current)); + + int err = lfs_bd_read(lfs, + pcache, rcache, sizeof(head), + head, 4*skip, &head, sizeof(head)); + head = lfs_fromle32(head); + if (err) { + return err; + } + + current -= 1 << skip; + } + + *block = head; + *off = pos; + return 0; +} + +#ifndef LFS_READONLY +static int lfs_ctz_extend(lfs_t *lfs, + lfs_cache_t *pcache, lfs_cache_t *rcache, + lfs_block_t head, lfs_size_t size, + lfs_block_t *block, lfs_off_t *off) { + while (true) { + // go ahead and grab a block + lfs_block_t nblock; + int err = lfs_alloc(lfs, &nblock); + if (err) { + return err; + } + + { + err = lfs_bd_erase(lfs, nblock); + if (err) { + if (err == LFS_ERR_CORRUPT) { + goto relocate; + } + return err; + } + + if (size == 0) { + *block = nblock; + *off = 0; + return 0; + } + + lfs_size_t noff = size - 1; + lfs_off_t index = lfs_ctz_index(lfs, &noff); + noff = noff + 1; + + // just copy out the last block if it is incomplete + if (noff != lfs->cfg->block_size) { + for (lfs_off_t i = 0; i < noff; i++) { + uint8_t data; + err = lfs_bd_read(lfs, + NULL, rcache, noff-i, + head, i, &data, 1); + if (err) { + return err; + } + + err = lfs_bd_prog(lfs, + pcache, rcache, true, + nblock, i, &data, 1); + if (err) { + if (err == LFS_ERR_CORRUPT) { + goto relocate; + } + return err; + } + } + + *block = nblock; + *off = noff; + return 0; + } + + // append block + index += 1; + lfs_size_t skips = lfs_ctz(index) + 1; + lfs_block_t nhead = head; + for (lfs_off_t i = 0; i < skips; i++) { + nhead = lfs_tole32(nhead); + err = lfs_bd_prog(lfs, pcache, rcache, true, + nblock, 4*i, &nhead, 4); + nhead = lfs_fromle32(nhead); + if (err) { + if (err == LFS_ERR_CORRUPT) { + goto relocate; + } + return err; + } + + if (i != skips-1) { + err = lfs_bd_read(lfs, + NULL, rcache, sizeof(nhead), + nhead, 4*i, &nhead, sizeof(nhead)); + nhead = lfs_fromle32(nhead); + if (err) { + return err; + } + } + } + + *block = nblock; + *off = 4*skips; + return 0; + } + +relocate: + LFS_DEBUG("Bad block at 0x%"PRIx32, nblock); + + // just clear cache and try a new block + lfs_cache_drop(lfs, pcache); + } +} +#endif + +static int lfs_ctz_traverse(lfs_t *lfs, + const lfs_cache_t *pcache, lfs_cache_t *rcache, + lfs_block_t head, lfs_size_t size, + int (*cb)(void*, lfs_block_t), void *data) { + if (size == 0) { + return 0; + } + + lfs_off_t index = lfs_ctz_index(lfs, &(lfs_off_t){size-1}); + + while (true) { + int err = cb(data, head); + if (err) { + return err; + } + + if (index == 0) { + return 0; + } + + lfs_block_t heads[2]; + int count = 2 - (index & 1); + err = lfs_bd_read(lfs, + pcache, rcache, count*sizeof(head), + head, 0, &heads, count*sizeof(head)); + heads[0] = lfs_fromle32(heads[0]); + heads[1] = lfs_fromle32(heads[1]); + if (err) { + return err; + } + + for (int i = 0; i < count-1; i++) { + err = cb(data, heads[i]); + if (err) { + return err; + } + } + + head = heads[count-1]; + index -= count; + } +} + + +/// Top level file operations /// +static int lfs_file_opencfg_(lfs_t *lfs, lfs_file_t *file, + const char *path, int flags, + const struct lfs_file_config *cfg) { +#ifndef LFS_READONLY + // deorphan if we haven't yet, needed at most once after poweron + if ((flags & LFS_O_WRONLY) == LFS_O_WRONLY) { + int err = lfs_fs_forceconsistency(lfs); + if (err) { + return err; + } + } +#else + LFS_ASSERT((flags & LFS_O_RDONLY) == LFS_O_RDONLY); +#endif + + // setup simple file details + int err; + file->cfg = cfg; + file->flags = flags; + file->pos = 0; + file->off = 0; + file->cache.buffer = NULL; + + // allocate entry for file if it doesn't exist + lfs_stag_t tag = lfs_dir_find(lfs, &file->m, &path, &file->id); + if (tag < 0 && !(tag == LFS_ERR_NOENT && file->id != 0x3ff)) { + err = tag; + goto cleanup; + } + + // get id, add to list of mdirs to catch update changes + file->type = LFS_TYPE_REG; + lfs_mlist_append(lfs, (struct lfs_mlist *)file); + +#ifdef LFS_READONLY + if (tag == LFS_ERR_NOENT) { + err = LFS_ERR_NOENT; + goto cleanup; +#else + if (tag == LFS_ERR_NOENT) { + if (!(flags & LFS_O_CREAT)) { + err = LFS_ERR_NOENT; + goto cleanup; + } + + // check that name fits + lfs_size_t nlen = strlen(path); + if (nlen > lfs->name_max) { + err = LFS_ERR_NAMETOOLONG; + goto cleanup; + } + + // get next slot and create entry to remember name + err = lfs_dir_commit(lfs, &file->m, LFS_MKATTRS( + {LFS_MKTAG(LFS_TYPE_CREATE, file->id, 0), NULL}, + {LFS_MKTAG(LFS_TYPE_REG, file->id, nlen), path}, + {LFS_MKTAG(LFS_TYPE_INLINESTRUCT, file->id, 0), NULL})); + + // it may happen that the file name doesn't fit in the metadata blocks, e.g., a 256 byte file name will + // not fit in a 128 byte block. + err = (err == LFS_ERR_NOSPC) ? LFS_ERR_NAMETOOLONG : err; + if (err) { + goto cleanup; + } + + tag = LFS_MKTAG(LFS_TYPE_INLINESTRUCT, 0, 0); + } else if (flags & LFS_O_EXCL) { + err = LFS_ERR_EXIST; + goto cleanup; +#endif + } else if (lfs_tag_type3(tag) != LFS_TYPE_REG) { + err = LFS_ERR_ISDIR; + goto cleanup; +#ifndef LFS_READONLY + } else if (flags & LFS_O_TRUNC) { + // truncate if requested + tag = LFS_MKTAG(LFS_TYPE_INLINESTRUCT, file->id, 0); + file->flags |= LFS_F_DIRTY; +#endif + } else { + // try to load what's on disk, if it's inlined we'll fix it later + tag = lfs_dir_get(lfs, &file->m, LFS_MKTAG(0x700, 0x3ff, 0), + LFS_MKTAG(LFS_TYPE_STRUCT, file->id, 8), &file->ctz); + if (tag < 0) { + err = tag; + goto cleanup; + } + lfs_ctz_fromle32(&file->ctz); + } + + // fetch attrs + for (unsigned i = 0; i < file->cfg->attr_count; i++) { + // if opened for read / read-write operations + if ((file->flags & LFS_O_RDONLY) == LFS_O_RDONLY) { + lfs_stag_t res = lfs_dir_get(lfs, &file->m, + LFS_MKTAG(0x7ff, 0x3ff, 0), + LFS_MKTAG(LFS_TYPE_USERATTR + file->cfg->attrs[i].type, + file->id, file->cfg->attrs[i].size), + file->cfg->attrs[i].buffer); + if (res < 0 && res != LFS_ERR_NOENT) { + err = res; + goto cleanup; + } + } + +#ifndef LFS_READONLY + // if opened for write / read-write operations + if ((file->flags & LFS_O_WRONLY) == LFS_O_WRONLY) { + if (file->cfg->attrs[i].size > lfs->attr_max) { + err = LFS_ERR_NOSPC; + goto cleanup; + } + + file->flags |= LFS_F_DIRTY; + } +#endif + } + + // allocate buffer if needed + if (file->cfg->buffer) { + file->cache.buffer = file->cfg->buffer; + } else { + file->cache.buffer = lfs_malloc(lfs->cfg->cache_size); + if (!file->cache.buffer) { + err = LFS_ERR_NOMEM; + goto cleanup; + } + } + + // zero to avoid information leak + lfs_cache_zero(lfs, &file->cache); + + if (lfs_tag_type3(tag) == LFS_TYPE_INLINESTRUCT) { + // load inline files + file->ctz.head = LFS_BLOCK_INLINE; + file->ctz.size = lfs_tag_size(tag); + file->flags |= LFS_F_INLINE; + file->cache.block = file->ctz.head; + file->cache.off = 0; + file->cache.size = lfs->cfg->cache_size; + + // don't always read (may be new/trunc file) + if (file->ctz.size > 0) { + lfs_stag_t res = lfs_dir_get(lfs, &file->m, + LFS_MKTAG(0x700, 0x3ff, 0), + LFS_MKTAG(LFS_TYPE_STRUCT, file->id, + lfs_min(file->cache.size, 0x3fe)), + file->cache.buffer); + if (res < 0) { + err = res; + goto cleanup; + } + } + } + + return 0; + +cleanup: + // clean up lingering resources +#ifndef LFS_READONLY + file->flags |= LFS_F_ERRED; +#endif + lfs_file_close_(lfs, file); + return err; +} + +#ifndef LFS_NO_MALLOC +static int lfs_file_open_(lfs_t *lfs, lfs_file_t *file, + const char *path, int flags) { + static const struct lfs_file_config defaults = {0}; + int err = lfs_file_opencfg_(lfs, file, path, flags, &defaults); + return err; +} +#endif + +static int lfs_file_close_(lfs_t *lfs, lfs_file_t *file) { +#ifndef LFS_READONLY + int err = lfs_file_sync_(lfs, file); +#else + int err = 0; +#endif + + // remove from list of mdirs + lfs_mlist_remove(lfs, (struct lfs_mlist*)file); + + // clean up memory + if (!file->cfg->buffer) { + lfs_free(file->cache.buffer); + } + + return err; +} + + +#ifndef LFS_READONLY +static int lfs_file_relocate(lfs_t *lfs, lfs_file_t *file) { + while (true) { + // just relocate what exists into new block + lfs_block_t nblock; + int err = lfs_alloc(lfs, &nblock); + if (err) { + return err; + } + + err = lfs_bd_erase(lfs, nblock); + if (err) { + if (err == LFS_ERR_CORRUPT) { + goto relocate; + } + return err; + } + + // either read from dirty cache or disk + for (lfs_off_t i = 0; i < file->off; i++) { + uint8_t data; + if (file->flags & LFS_F_INLINE) { + err = lfs_dir_getread(lfs, &file->m, + // note we evict inline files before they can be dirty + NULL, &file->cache, file->off-i, + LFS_MKTAG(0xfff, 0x1ff, 0), + LFS_MKTAG(LFS_TYPE_INLINESTRUCT, file->id, 0), + i, &data, 1); + if (err) { + return err; + } + } else { + err = lfs_bd_read(lfs, + &file->cache, &lfs->rcache, file->off-i, + file->block, i, &data, 1); + if (err) { + return err; + } + } + + err = lfs_bd_prog(lfs, + &lfs->pcache, &lfs->rcache, true, + nblock, i, &data, 1); + if (err) { + if (err == LFS_ERR_CORRUPT) { + goto relocate; + } + return err; + } + } + + // copy over new state of file + memcpy(file->cache.buffer, lfs->pcache.buffer, lfs->cfg->cache_size); + file->cache.block = lfs->pcache.block; + file->cache.off = lfs->pcache.off; + file->cache.size = lfs->pcache.size; + lfs_cache_zero(lfs, &lfs->pcache); + + file->block = nblock; + file->flags |= LFS_F_WRITING; + return 0; + +relocate: + LFS_DEBUG("Bad block at 0x%"PRIx32, nblock); + + // just clear cache and try a new block + lfs_cache_drop(lfs, &lfs->pcache); + } +} +#endif + +#ifndef LFS_READONLY +static int lfs_file_outline(lfs_t *lfs, lfs_file_t *file) { + file->off = file->pos; + lfs_alloc_ckpoint(lfs); + int err = lfs_file_relocate(lfs, file); + if (err) { + return err; + } + + file->flags &= ~LFS_F_INLINE; + return 0; +} +#endif + +static int lfs_file_flush(lfs_t *lfs, lfs_file_t *file) { + if (file->flags & LFS_F_READING) { + if (!(file->flags & LFS_F_INLINE)) { + lfs_cache_drop(lfs, &file->cache); + } + file->flags &= ~LFS_F_READING; + } + +#ifndef LFS_READONLY + if (file->flags & LFS_F_WRITING) { + lfs_off_t pos = file->pos; + + if (!(file->flags & LFS_F_INLINE)) { + // copy over anything after current branch + lfs_file_t orig = { + .ctz.head = file->ctz.head, + .ctz.size = file->ctz.size, + .flags = LFS_O_RDONLY, + .pos = file->pos, + .cache = lfs->rcache, + }; + lfs_cache_drop(lfs, &lfs->rcache); + + while (file->pos < file->ctz.size) { + // copy over a byte at a time, leave it up to caching + // to make this efficient + uint8_t data; + lfs_ssize_t res = lfs_file_flushedread(lfs, &orig, &data, 1); + if (res < 0) { + return res; + } + + res = lfs_file_flushedwrite(lfs, file, &data, 1); + if (res < 0) { + return res; + } + + // keep our reference to the rcache in sync + if (lfs->rcache.block != LFS_BLOCK_NULL) { + lfs_cache_drop(lfs, &orig.cache); + lfs_cache_drop(lfs, &lfs->rcache); + } + } + + // write out what we have + while (true) { + int err = lfs_bd_flush(lfs, &file->cache, &lfs->rcache, true); + if (err) { + if (err == LFS_ERR_CORRUPT) { + goto relocate; + } + return err; + } + + break; + +relocate: + LFS_DEBUG("Bad block at 0x%"PRIx32, file->block); + err = lfs_file_relocate(lfs, file); + if (err) { + return err; + } + } + } else { + file->pos = lfs_max(file->pos, file->ctz.size); + } + + // actual file updates + file->ctz.head = file->block; + file->ctz.size = file->pos; + file->flags &= ~LFS_F_WRITING; + file->flags |= LFS_F_DIRTY; + + file->pos = pos; + } +#endif + + return 0; +} + +#ifndef LFS_READONLY +static int lfs_file_sync_(lfs_t *lfs, lfs_file_t *file) { + if (file->flags & LFS_F_ERRED) { + // it's not safe to do anything if our file errored + return 0; + } + + int err = lfs_file_flush(lfs, file); + if (err) { + file->flags |= LFS_F_ERRED; + return err; + } + + + if ((file->flags & LFS_F_DIRTY) && + !lfs_pair_isnull(file->m.pair)) { + // before we commit metadata, we need sync the disk to make sure + // data writes don't complete after metadata writes + if (!(file->flags & LFS_F_INLINE)) { + err = lfs_bd_sync(lfs, &lfs->pcache, &lfs->rcache, false); + if (err) { + return err; + } + } + + // update dir entry + uint16_t type; + const void *buffer; + lfs_size_t size; + struct lfs_ctz ctz; + if (file->flags & LFS_F_INLINE) { + // inline the whole file + type = LFS_TYPE_INLINESTRUCT; + buffer = file->cache.buffer; + size = file->ctz.size; + } else { + // update the ctz reference + type = LFS_TYPE_CTZSTRUCT; + // copy ctz so alloc will work during a relocate + ctz = file->ctz; + lfs_ctz_tole32(&ctz); + buffer = &ctz; + size = sizeof(ctz); + } + + // commit file data and attributes + err = lfs_dir_commit(lfs, &file->m, LFS_MKATTRS( + {LFS_MKTAG(type, file->id, size), buffer}, + {LFS_MKTAG(LFS_FROM_USERATTRS, file->id, + file->cfg->attr_count), file->cfg->attrs})); + if (err) { + file->flags |= LFS_F_ERRED; + return err; + } + + file->flags &= ~LFS_F_DIRTY; + } + + return 0; +} +#endif + +static lfs_ssize_t lfs_file_flushedread(lfs_t *lfs, lfs_file_t *file, + void *buffer, lfs_size_t size) { + uint8_t *data = buffer; + lfs_size_t nsize = size; + + if (file->pos >= file->ctz.size) { + // eof if past end + return 0; + } + + size = lfs_min(size, file->ctz.size - file->pos); + nsize = size; + + while (nsize > 0) { + // check if we need a new block + if (!(file->flags & LFS_F_READING) || + file->off == lfs->cfg->block_size) { + if (!(file->flags & LFS_F_INLINE)) { + int err = lfs_ctz_find(lfs, NULL, &file->cache, + file->ctz.head, file->ctz.size, + file->pos, &file->block, &file->off); + if (err) { + return err; + } + } else { + file->block = LFS_BLOCK_INLINE; + file->off = file->pos; + } + + file->flags |= LFS_F_READING; + } + + // read as much as we can in current block + lfs_size_t diff = lfs_min(nsize, lfs->cfg->block_size - file->off); + if (file->flags & LFS_F_INLINE) { + int err = lfs_dir_getread(lfs, &file->m, + NULL, &file->cache, lfs->cfg->block_size, + LFS_MKTAG(0xfff, 0x1ff, 0), + LFS_MKTAG(LFS_TYPE_INLINESTRUCT, file->id, 0), + file->off, data, diff); + if (err) { + return err; + } + } else { + int err = lfs_bd_read(lfs, + NULL, &file->cache, lfs->cfg->block_size, + file->block, file->off, data, diff); + if (err) { + return err; + } + } + + file->pos += diff; + file->off += diff; + data += diff; + nsize -= diff; + } + + return size; +} + +static lfs_ssize_t lfs_file_read_(lfs_t *lfs, lfs_file_t *file, + void *buffer, lfs_size_t size) { + LFS_ASSERT((file->flags & LFS_O_RDONLY) == LFS_O_RDONLY); + +#ifndef LFS_READONLY + if (file->flags & LFS_F_WRITING) { + // flush out any writes + int err = lfs_file_flush(lfs, file); + if (err) { + return err; + } + } +#endif + + return lfs_file_flushedread(lfs, file, buffer, size); +} + + +#ifndef LFS_READONLY +static lfs_ssize_t lfs_file_flushedwrite(lfs_t *lfs, lfs_file_t *file, + const void *buffer, lfs_size_t size) { + const uint8_t *data = buffer; + lfs_size_t nsize = size; + + if ((file->flags & LFS_F_INLINE) && + lfs_max(file->pos+nsize, file->ctz.size) > lfs->inline_max) { + // inline file doesn't fit anymore + int err = lfs_file_outline(lfs, file); + if (err) { + file->flags |= LFS_F_ERRED; + return err; + } + } + + while (nsize > 0) { + // check if we need a new block + if (!(file->flags & LFS_F_WRITING) || + file->off == lfs->cfg->block_size) { + if (!(file->flags & LFS_F_INLINE)) { + if (!(file->flags & LFS_F_WRITING) && file->pos > 0) { + // find out which block we're extending from + int err = lfs_ctz_find(lfs, NULL, &file->cache, + file->ctz.head, file->ctz.size, + file->pos-1, &file->block, &(lfs_off_t){0}); + if (err) { + file->flags |= LFS_F_ERRED; + return err; + } + + // mark cache as dirty since we may have read data into it + lfs_cache_zero(lfs, &file->cache); + } + + // extend file with new blocks + lfs_alloc_ckpoint(lfs); + int err = lfs_ctz_extend(lfs, &file->cache, &lfs->rcache, + file->block, file->pos, + &file->block, &file->off); + if (err) { + file->flags |= LFS_F_ERRED; + return err; + } + } else { + file->block = LFS_BLOCK_INLINE; + file->off = file->pos; + } + + file->flags |= LFS_F_WRITING; + } + + // program as much as we can in current block + lfs_size_t diff = lfs_min(nsize, lfs->cfg->block_size - file->off); + while (true) { + int err = lfs_bd_prog(lfs, &file->cache, &lfs->rcache, true, + file->block, file->off, data, diff); + if (err) { + if (err == LFS_ERR_CORRUPT) { + goto relocate; + } + file->flags |= LFS_F_ERRED; + return err; + } + + break; +relocate: + err = lfs_file_relocate(lfs, file); + if (err) { + file->flags |= LFS_F_ERRED; + return err; + } + } + + file->pos += diff; + file->off += diff; + data += diff; + nsize -= diff; + + lfs_alloc_ckpoint(lfs); + } + + return size; +} + +static lfs_ssize_t lfs_file_write_(lfs_t *lfs, lfs_file_t *file, + const void *buffer, lfs_size_t size) { + LFS_ASSERT((file->flags & LFS_O_WRONLY) == LFS_O_WRONLY); + + if (file->flags & LFS_F_READING) { + // drop any reads + int err = lfs_file_flush(lfs, file); + if (err) { + return err; + } + } + + if ((file->flags & LFS_O_APPEND) && file->pos < file->ctz.size) { + file->pos = file->ctz.size; + } + + if (file->pos + size > lfs->file_max) { + // Larger than file limit? + return LFS_ERR_FBIG; + } + + if (!(file->flags & LFS_F_WRITING) && file->pos > file->ctz.size) { + // fill with zeros + lfs_off_t pos = file->pos; + file->pos = file->ctz.size; + + while (file->pos < pos) { + lfs_ssize_t res = lfs_file_flushedwrite(lfs, file, &(uint8_t){0}, 1); + if (res < 0) { + return res; + } + } + } + + lfs_ssize_t nsize = lfs_file_flushedwrite(lfs, file, buffer, size); + if (nsize < 0) { + return nsize; + } + + file->flags &= ~LFS_F_ERRED; + return nsize; +} +#endif + +static lfs_soff_t lfs_file_seek_(lfs_t *lfs, lfs_file_t *file, + lfs_soff_t off, int whence) { + // find new pos + lfs_off_t npos = file->pos; + if (whence == LFS_SEEK_SET) { + npos = off; + } else if (whence == LFS_SEEK_CUR) { + if ((lfs_soff_t)file->pos + off < 0) { + return LFS_ERR_INVAL; + } else { + npos = file->pos + off; + } + } else if (whence == LFS_SEEK_END) { + lfs_soff_t res = lfs_file_size_(lfs, file) + off; + if (res < 0) { + return LFS_ERR_INVAL; + } else { + npos = res; + } + } + + if (npos > lfs->file_max) { + // file position out of range + return LFS_ERR_INVAL; + } + + if (file->pos == npos) { + // noop - position has not changed + return npos; + } + + // if we're only reading and our new offset is still in the file's cache + // we can avoid flushing and needing to reread the data + if ( +#ifndef LFS_READONLY + !(file->flags & LFS_F_WRITING) +#else + true +#endif + ) { + int oindex = lfs_ctz_index(lfs, &(lfs_off_t){file->pos}); + lfs_off_t noff = npos; + int nindex = lfs_ctz_index(lfs, &noff); + if (oindex == nindex + && noff >= file->cache.off + && noff < file->cache.off + file->cache.size) { + file->pos = npos; + file->off = noff; + return npos; + } + } + + // write out everything beforehand, may be noop if rdonly + int err = lfs_file_flush(lfs, file); + if (err) { + return err; + } + + // update pos + file->pos = npos; + return npos; +} + +#ifndef LFS_READONLY +static int lfs_file_truncate_(lfs_t *lfs, lfs_file_t *file, lfs_off_t size) { + LFS_ASSERT((file->flags & LFS_O_WRONLY) == LFS_O_WRONLY); + + if (size > LFS_FILE_MAX) { + return LFS_ERR_INVAL; + } + + lfs_off_t pos = file->pos; + lfs_off_t oldsize = lfs_file_size_(lfs, file); + if (size < oldsize) { + // revert to inline file? + if (size <= lfs->inline_max) { + // flush+seek to head + lfs_soff_t res = lfs_file_seek_(lfs, file, 0, LFS_SEEK_SET); + if (res < 0) { + return (int)res; + } + + // read our data into rcache temporarily + lfs_cache_drop(lfs, &lfs->rcache); + res = lfs_file_flushedread(lfs, file, + lfs->rcache.buffer, size); + if (res < 0) { + return (int)res; + } + + file->ctz.head = LFS_BLOCK_INLINE; + file->ctz.size = size; + file->flags |= LFS_F_DIRTY | LFS_F_READING | LFS_F_INLINE; + file->cache.block = file->ctz.head; + file->cache.off = 0; + file->cache.size = lfs->cfg->cache_size; + memcpy(file->cache.buffer, lfs->rcache.buffer, size); + + } else { + // need to flush since directly changing metadata + int err = lfs_file_flush(lfs, file); + if (err) { + return err; + } + + // lookup new head in ctz skip list + err = lfs_ctz_find(lfs, NULL, &file->cache, + file->ctz.head, file->ctz.size, + size-1, &file->block, &(lfs_off_t){0}); + if (err) { + return err; + } + + // need to set pos/block/off consistently so seeking back to + // the old position does not get confused + file->pos = size; + file->ctz.head = file->block; + file->ctz.size = size; + file->flags |= LFS_F_DIRTY | LFS_F_READING; + } + } else if (size > oldsize) { + // flush+seek if not already at end + lfs_soff_t res = lfs_file_seek_(lfs, file, 0, LFS_SEEK_END); + if (res < 0) { + return (int)res; + } + + // fill with zeros + while (file->pos < size) { + res = lfs_file_write_(lfs, file, &(uint8_t){0}, 1); + if (res < 0) { + return (int)res; + } + } + } + + // restore pos + lfs_soff_t res = lfs_file_seek_(lfs, file, pos, LFS_SEEK_SET); + if (res < 0) { + return (int)res; + } + + return 0; +} +#endif + +static lfs_soff_t lfs_file_tell_(lfs_t *lfs, lfs_file_t *file) { + (void)lfs; + return file->pos; +} + +static int lfs_file_rewind_(lfs_t *lfs, lfs_file_t *file) { + lfs_soff_t res = lfs_file_seek_(lfs, file, 0, LFS_SEEK_SET); + if (res < 0) { + return (int)res; + } + + return 0; +} + +static lfs_soff_t lfs_file_size_(lfs_t *lfs, lfs_file_t *file) { + (void)lfs; + +#ifndef LFS_READONLY + if (file->flags & LFS_F_WRITING) { + return lfs_max(file->pos, file->ctz.size); + } +#endif + + return file->ctz.size; +} + + +/// General fs operations /// +static int lfs_stat_(lfs_t *lfs, const char *path, struct lfs_info *info) { + lfs_mdir_t cwd; + lfs_stag_t tag = lfs_dir_find(lfs, &cwd, &path, NULL); + if (tag < 0) { + return (int)tag; + } + + return lfs_dir_getinfo(lfs, &cwd, lfs_tag_id(tag), info); +} + +#ifndef LFS_READONLY +static int lfs_remove_(lfs_t *lfs, const char *path) { + // deorphan if we haven't yet, needed at most once after poweron + int err = lfs_fs_forceconsistency(lfs); + if (err) { + return err; + } + + lfs_mdir_t cwd; + lfs_stag_t tag = lfs_dir_find(lfs, &cwd, &path, NULL); + if (tag < 0 || lfs_tag_id(tag) == 0x3ff) { + return (tag < 0) ? (int)tag : LFS_ERR_INVAL; + } + + struct lfs_mlist dir; + dir.next = lfs->mlist; + if (lfs_tag_type3(tag) == LFS_TYPE_DIR) { + // must be empty before removal + lfs_block_t pair[2]; + lfs_stag_t res = lfs_dir_get(lfs, &cwd, LFS_MKTAG(0x700, 0x3ff, 0), + LFS_MKTAG(LFS_TYPE_STRUCT, lfs_tag_id(tag), 8), pair); + if (res < 0) { + return (int)res; + } + lfs_pair_fromle32(pair); + + err = lfs_dir_fetch(lfs, &dir.m, pair); + if (err) { + return err; + } + + if (dir.m.count > 0 || dir.m.split) { + return LFS_ERR_NOTEMPTY; + } + + // mark fs as orphaned + err = lfs_fs_preporphans(lfs, +1); + if (err) { + return err; + } + + // I know it's crazy but yes, dir can be changed by our parent's + // commit (if predecessor is child) + dir.type = 0; + dir.id = 0; + lfs->mlist = &dir; + } + + // delete the entry + err = lfs_dir_commit(lfs, &cwd, LFS_MKATTRS( + {LFS_MKTAG(LFS_TYPE_DELETE, lfs_tag_id(tag), 0), NULL})); + if (err) { + lfs->mlist = dir.next; + return err; + } + + lfs->mlist = dir.next; + if (lfs_tag_type3(tag) == LFS_TYPE_DIR) { + // fix orphan + err = lfs_fs_preporphans(lfs, -1); + if (err) { + return err; + } + + err = lfs_fs_pred(lfs, dir.m.pair, &cwd); + if (err) { + return err; + } + + err = lfs_dir_drop(lfs, &cwd, &dir.m); + if (err) { + return err; + } + } + + return 0; +} +#endif + +#ifndef LFS_READONLY +static int lfs_rename_(lfs_t *lfs, const char *oldpath, const char *newpath) { + // deorphan if we haven't yet, needed at most once after poweron + int err = lfs_fs_forceconsistency(lfs); + if (err) { + return err; + } + + // find old entry + lfs_mdir_t oldcwd; + lfs_stag_t oldtag = lfs_dir_find(lfs, &oldcwd, &oldpath, NULL); + if (oldtag < 0 || lfs_tag_id(oldtag) == 0x3ff) { + return (oldtag < 0) ? (int)oldtag : LFS_ERR_INVAL; + } + + // find new entry + lfs_mdir_t newcwd; + uint16_t newid; + lfs_stag_t prevtag = lfs_dir_find(lfs, &newcwd, &newpath, &newid); + if ((prevtag < 0 || lfs_tag_id(prevtag) == 0x3ff) && + !(prevtag == LFS_ERR_NOENT && newid != 0x3ff)) { + return (prevtag < 0) ? (int)prevtag : LFS_ERR_INVAL; + } + + // if we're in the same pair there's a few special cases... + bool samepair = (lfs_pair_cmp(oldcwd.pair, newcwd.pair) == 0); + uint16_t newoldid = lfs_tag_id(oldtag); + + struct lfs_mlist prevdir; + prevdir.next = lfs->mlist; + if (prevtag == LFS_ERR_NOENT) { + // check that name fits + lfs_size_t nlen = strlen(newpath); + if (nlen > lfs->name_max) { + return LFS_ERR_NAMETOOLONG; + } + + // there is a small chance we are being renamed in the same + // directory/ to an id less than our old id, the global update + // to handle this is a bit messy + if (samepair && newid <= newoldid) { + newoldid += 1; + } + } else if (lfs_tag_type3(prevtag) != lfs_tag_type3(oldtag)) { + return (lfs_tag_type3(prevtag) == LFS_TYPE_DIR) + ? LFS_ERR_ISDIR + : LFS_ERR_NOTDIR; + } else if (samepair && newid == newoldid) { + // we're renaming to ourselves?? + return 0; + } else if (lfs_tag_type3(prevtag) == LFS_TYPE_DIR) { + // must be empty before removal + lfs_block_t prevpair[2]; + lfs_stag_t res = lfs_dir_get(lfs, &newcwd, LFS_MKTAG(0x700, 0x3ff, 0), + LFS_MKTAG(LFS_TYPE_STRUCT, newid, 8), prevpair); + if (res < 0) { + return (int)res; + } + lfs_pair_fromle32(prevpair); + + // must be empty before removal + err = lfs_dir_fetch(lfs, &prevdir.m, prevpair); + if (err) { + return err; + } + + if (prevdir.m.count > 0 || prevdir.m.split) { + return LFS_ERR_NOTEMPTY; + } + + // mark fs as orphaned + err = lfs_fs_preporphans(lfs, +1); + if (err) { + return err; + } + + // I know it's crazy but yes, dir can be changed by our parent's + // commit (if predecessor is child) + prevdir.type = 0; + prevdir.id = 0; + lfs->mlist = &prevdir; + } + + if (!samepair) { + lfs_fs_prepmove(lfs, newoldid, oldcwd.pair); + } + + // move over all attributes + err = lfs_dir_commit(lfs, &newcwd, LFS_MKATTRS( + {LFS_MKTAG_IF(prevtag != LFS_ERR_NOENT, + LFS_TYPE_DELETE, newid, 0), NULL}, + {LFS_MKTAG(LFS_TYPE_CREATE, newid, 0), NULL}, + {LFS_MKTAG(lfs_tag_type3(oldtag), newid, strlen(newpath)), newpath}, + {LFS_MKTAG(LFS_FROM_MOVE, newid, lfs_tag_id(oldtag)), &oldcwd}, + {LFS_MKTAG_IF(samepair, + LFS_TYPE_DELETE, newoldid, 0), NULL})); + if (err) { + lfs->mlist = prevdir.next; + return err; + } + + // let commit clean up after move (if we're different! otherwise move + // logic already fixed it for us) + if (!samepair && lfs_gstate_hasmove(&lfs->gstate)) { + // prep gstate and delete move id + lfs_fs_prepmove(lfs, 0x3ff, NULL); + err = lfs_dir_commit(lfs, &oldcwd, LFS_MKATTRS( + {LFS_MKTAG(LFS_TYPE_DELETE, lfs_tag_id(oldtag), 0), NULL})); + if (err) { + lfs->mlist = prevdir.next; + return err; + } + } + + lfs->mlist = prevdir.next; + if (prevtag != LFS_ERR_NOENT + && lfs_tag_type3(prevtag) == LFS_TYPE_DIR) { + // fix orphan + err = lfs_fs_preporphans(lfs, -1); + if (err) { + return err; + } + + err = lfs_fs_pred(lfs, prevdir.m.pair, &newcwd); + if (err) { + return err; + } + + err = lfs_dir_drop(lfs, &newcwd, &prevdir.m); + if (err) { + return err; + } + } + + return 0; +} +#endif + +static lfs_ssize_t lfs_getattr_(lfs_t *lfs, const char *path, + uint8_t type, void *buffer, lfs_size_t size) { + lfs_mdir_t cwd; + lfs_stag_t tag = lfs_dir_find(lfs, &cwd, &path, NULL); + if (tag < 0) { + return tag; + } + + uint16_t id = lfs_tag_id(tag); + if (id == 0x3ff) { + // special case for root + id = 0; + int err = lfs_dir_fetch(lfs, &cwd, lfs->root); + if (err) { + return err; + } + } + + tag = lfs_dir_get(lfs, &cwd, LFS_MKTAG(0x7ff, 0x3ff, 0), + LFS_MKTAG(LFS_TYPE_USERATTR + type, + id, lfs_min(size, lfs->attr_max)), + buffer); + if (tag < 0) { + if (tag == LFS_ERR_NOENT) { + return LFS_ERR_NOATTR; + } + + return tag; + } + + return lfs_tag_size(tag); +} + +#ifndef LFS_READONLY +static int lfs_commitattr(lfs_t *lfs, const char *path, + uint8_t type, const void *buffer, lfs_size_t size) { + lfs_mdir_t cwd; + lfs_stag_t tag = lfs_dir_find(lfs, &cwd, &path, NULL); + if (tag < 0) { + return tag; + } + + uint16_t id = lfs_tag_id(tag); + if (id == 0x3ff) { + // special case for root + id = 0; + int err = lfs_dir_fetch(lfs, &cwd, lfs->root); + if (err) { + return err; + } + } + + return lfs_dir_commit(lfs, &cwd, LFS_MKATTRS( + {LFS_MKTAG(LFS_TYPE_USERATTR + type, id, size), buffer})); +} +#endif + +#ifndef LFS_READONLY +static int lfs_setattr_(lfs_t *lfs, const char *path, + uint8_t type, const void *buffer, lfs_size_t size) { + if (size > lfs->attr_max) { + return LFS_ERR_NOSPC; + } + + return lfs_commitattr(lfs, path, type, buffer, size); +} +#endif + +#ifndef LFS_READONLY +static int lfs_removeattr_(lfs_t *lfs, const char *path, uint8_t type) { + return lfs_commitattr(lfs, path, type, NULL, 0x3ff); +} +#endif + + +/// Filesystem operations /// + +// compile time checks, see lfs.h for why these limits exist +#if LFS_NAME_MAX > 1022 +#error "Invalid LFS_NAME_MAX, must be <= 1022" +#endif + +#if LFS_FILE_MAX > 2147483647 +#error "Invalid LFS_FILE_MAX, must be <= 2147483647" +#endif + +#if LFS_ATTR_MAX > 1022 +#error "Invalid LFS_ATTR_MAX, must be <= 1022" +#endif + +// common filesystem initialization +static int lfs_init(lfs_t *lfs, const struct lfs_config *cfg) { + lfs->cfg = cfg; + lfs->block_count = cfg->block_count; // May be 0 + int err = 0; + +#ifdef LFS_MULTIVERSION + // this driver only supports minor version < current minor version + LFS_ASSERT(!lfs->cfg->disk_version || ( + (0xffff & (lfs->cfg->disk_version >> 16)) + == LFS_DISK_VERSION_MAJOR + && (0xffff & (lfs->cfg->disk_version >> 0)) + <= LFS_DISK_VERSION_MINOR)); +#endif + + // check that bool is a truthy-preserving type + // + // note the most common reason for this failure is a before-c99 compiler, + // which littlefs currently does not support + LFS_ASSERT((bool)0x80000000); + + // validate that the lfs-cfg sizes were initiated properly before + // performing any arithmetic logics with them + LFS_ASSERT(lfs->cfg->read_size != 0); + LFS_ASSERT(lfs->cfg->prog_size != 0); + LFS_ASSERT(lfs->cfg->cache_size != 0); + + // check that block size is a multiple of cache size is a multiple + // of prog and read sizes + LFS_ASSERT(lfs->cfg->cache_size % lfs->cfg->read_size == 0); + LFS_ASSERT(lfs->cfg->cache_size % lfs->cfg->prog_size == 0); + LFS_ASSERT(lfs->cfg->block_size % lfs->cfg->cache_size == 0); + + // check that the block size is large enough to fit all ctz pointers + LFS_ASSERT(lfs->cfg->block_size >= 128); + // this is the exact calculation for all ctz pointers, if this fails + // and the simpler assert above does not, math must be broken + LFS_ASSERT(4*lfs_npw2(0xffffffff / (lfs->cfg->block_size-2*4)) + <= lfs->cfg->block_size); + + // block_cycles = 0 is no longer supported. + // + // block_cycles is the number of erase cycles before littlefs evicts + // metadata logs as a part of wear leveling. Suggested values are in the + // range of 100-1000, or set block_cycles to -1 to disable block-level + // wear-leveling. + LFS_ASSERT(lfs->cfg->block_cycles != 0); + + // check that compact_thresh makes sense + // + // metadata can't be compacted below block_size/2, and metadata can't + // exceed a block_size + LFS_ASSERT(lfs->cfg->compact_thresh == 0 + || lfs->cfg->compact_thresh >= lfs->cfg->block_size/2); + LFS_ASSERT(lfs->cfg->compact_thresh == (lfs_size_t)-1 + || lfs->cfg->compact_thresh <= lfs->cfg->block_size); + + // setup read cache + if (lfs->cfg->read_buffer) { + lfs->rcache.buffer = lfs->cfg->read_buffer; + } else { + lfs->rcache.buffer = lfs_malloc(lfs->cfg->cache_size); + if (!lfs->rcache.buffer) { + err = LFS_ERR_NOMEM; + goto cleanup; + } + } + + // setup program cache + if (lfs->cfg->prog_buffer) { + lfs->pcache.buffer = lfs->cfg->prog_buffer; + } else { + lfs->pcache.buffer = lfs_malloc(lfs->cfg->cache_size); + if (!lfs->pcache.buffer) { + err = LFS_ERR_NOMEM; + goto cleanup; + } + } + + // zero to avoid information leaks + lfs_cache_zero(lfs, &lfs->rcache); + lfs_cache_zero(lfs, &lfs->pcache); + + // setup lookahead buffer, note mount finishes initializing this after + // we establish a decent pseudo-random seed + LFS_ASSERT(lfs->cfg->lookahead_size > 0); + if (lfs->cfg->lookahead_buffer) { + lfs->lookahead.buffer = lfs->cfg->lookahead_buffer; + } else { + lfs->lookahead.buffer = lfs_malloc(lfs->cfg->lookahead_size); + if (!lfs->lookahead.buffer) { + err = LFS_ERR_NOMEM; + goto cleanup; + } + } + + // check that the size limits are sane + LFS_ASSERT(lfs->cfg->name_max <= LFS_NAME_MAX); + lfs->name_max = lfs->cfg->name_max; + if (!lfs->name_max) { + lfs->name_max = LFS_NAME_MAX; + } + + LFS_ASSERT(lfs->cfg->file_max <= LFS_FILE_MAX); + lfs->file_max = lfs->cfg->file_max; + if (!lfs->file_max) { + lfs->file_max = LFS_FILE_MAX; + } + + LFS_ASSERT(lfs->cfg->attr_max <= LFS_ATTR_MAX); + lfs->attr_max = lfs->cfg->attr_max; + if (!lfs->attr_max) { + lfs->attr_max = LFS_ATTR_MAX; + } + + LFS_ASSERT(lfs->cfg->metadata_max <= lfs->cfg->block_size); + + LFS_ASSERT(lfs->cfg->inline_max == (lfs_size_t)-1 + || lfs->cfg->inline_max <= lfs->cfg->cache_size); + LFS_ASSERT(lfs->cfg->inline_max == (lfs_size_t)-1 + || lfs->cfg->inline_max <= lfs->attr_max); + LFS_ASSERT(lfs->cfg->inline_max == (lfs_size_t)-1 + || lfs->cfg->inline_max <= ((lfs->cfg->metadata_max) + ? lfs->cfg->metadata_max + : lfs->cfg->block_size)/8); + lfs->inline_max = lfs->cfg->inline_max; + if (lfs->inline_max == (lfs_size_t)-1) { + lfs->inline_max = 0; + } else if (lfs->inline_max == 0) { + lfs->inline_max = lfs_min( + lfs->cfg->cache_size, + lfs_min( + lfs->attr_max, + ((lfs->cfg->metadata_max) + ? lfs->cfg->metadata_max + : lfs->cfg->block_size)/8)); + } + + // setup default state + lfs->root[0] = LFS_BLOCK_NULL; + lfs->root[1] = LFS_BLOCK_NULL; + lfs->mlist = NULL; + lfs->seed = 0; + lfs->gdisk = (lfs_gstate_t){0}; + lfs->gstate = (lfs_gstate_t){0}; + lfs->gdelta = (lfs_gstate_t){0}; +#ifdef LFS_MIGRATE + lfs->lfs1 = NULL; +#endif + + return 0; + +cleanup: + lfs_deinit(lfs); + return err; +} + +static int lfs_deinit(lfs_t *lfs) { + // free allocated memory + if (!lfs->cfg->read_buffer) { + lfs_free(lfs->rcache.buffer); + } + + if (!lfs->cfg->prog_buffer) { + lfs_free(lfs->pcache.buffer); + } + + if (!lfs->cfg->lookahead_buffer) { + lfs_free(lfs->lookahead.buffer); + } + + return 0; +} + + + +#ifndef LFS_READONLY +static int lfs_format_(lfs_t *lfs, const struct lfs_config *cfg) { + int err = 0; + { + err = lfs_init(lfs, cfg); + if (err) { + return err; + } + + LFS_ASSERT(cfg->block_count != 0); + + // create free lookahead + memset(lfs->lookahead.buffer, 0, lfs->cfg->lookahead_size); + lfs->lookahead.start = 0; + lfs->lookahead.size = lfs_min(8*lfs->cfg->lookahead_size, + lfs->block_count); + lfs->lookahead.next = 0; + lfs_alloc_ckpoint(lfs); + + // create root dir + lfs_mdir_t root; + err = lfs_dir_alloc(lfs, &root); + if (err) { + goto cleanup; + } + + // write one superblock + lfs_superblock_t superblock = { + .version = lfs_fs_disk_version(lfs), + .block_size = lfs->cfg->block_size, + .block_count = lfs->block_count, + .name_max = lfs->name_max, + .file_max = lfs->file_max, + .attr_max = lfs->attr_max, + }; + + lfs_superblock_tole32(&superblock); + err = lfs_dir_commit(lfs, &root, LFS_MKATTRS( + {LFS_MKTAG(LFS_TYPE_CREATE, 0, 0), NULL}, + {LFS_MKTAG(LFS_TYPE_SUPERBLOCK, 0, 8), "littlefs"}, + {LFS_MKTAG(LFS_TYPE_INLINESTRUCT, 0, sizeof(superblock)), + &superblock})); + if (err) { + goto cleanup; + } + + // force compaction to prevent accidentally mounting any + // older version of littlefs that may live on disk + root.erased = false; + err = lfs_dir_commit(lfs, &root, NULL, 0); + if (err) { + goto cleanup; + } + + // sanity check that fetch works + err = lfs_dir_fetch(lfs, &root, (const lfs_block_t[2]){0, 1}); + if (err) { + goto cleanup; + } + } + +cleanup: + lfs_deinit(lfs); + return err; + +} +#endif + +static int lfs_mount_(lfs_t *lfs, const struct lfs_config *cfg) { + int err = lfs_init(lfs, cfg); + if (err) { + return err; + } + + // scan directory blocks for superblock and any global updates + lfs_mdir_t dir = {.tail = {0, 1}}; + lfs_block_t tortoise[2] = {LFS_BLOCK_NULL, LFS_BLOCK_NULL}; + lfs_size_t tortoise_i = 1; + lfs_size_t tortoise_period = 1; + while (!lfs_pair_isnull(dir.tail)) { + // detect cycles with Brent's algorithm + if (lfs_pair_issync(dir.tail, tortoise)) { + LFS_WARN("Cycle detected in tail list"); + err = LFS_ERR_CORRUPT; + goto cleanup; + } + if (tortoise_i == tortoise_period) { + tortoise[0] = dir.tail[0]; + tortoise[1] = dir.tail[1]; + tortoise_i = 0; + tortoise_period *= 2; + } + tortoise_i += 1; + + // fetch next block in tail list + lfs_stag_t tag = lfs_dir_fetchmatch(lfs, &dir, dir.tail, + LFS_MKTAG(0x7ff, 0x3ff, 0), + LFS_MKTAG(LFS_TYPE_SUPERBLOCK, 0, 8), + NULL, + lfs_dir_find_match, &(struct lfs_dir_find_match){ + lfs, "littlefs", 8}); + if (tag < 0) { + err = tag; + goto cleanup; + } + + // has superblock? + if (tag && !lfs_tag_isdelete(tag)) { + // update root + lfs->root[0] = dir.pair[0]; + lfs->root[1] = dir.pair[1]; + + // grab superblock + lfs_superblock_t superblock; + tag = lfs_dir_get(lfs, &dir, LFS_MKTAG(0x7ff, 0x3ff, 0), + LFS_MKTAG(LFS_TYPE_INLINESTRUCT, 0, sizeof(superblock)), + &superblock); + if (tag < 0) { + err = tag; + goto cleanup; + } + lfs_superblock_fromle32(&superblock); + + // check version + uint16_t major_version = (0xffff & (superblock.version >> 16)); + uint16_t minor_version = (0xffff & (superblock.version >> 0)); + if (major_version != lfs_fs_disk_version_major(lfs) + || minor_version > lfs_fs_disk_version_minor(lfs)) { + LFS_ERROR("Invalid version " + "v%"PRIu16".%"PRIu16" != v%"PRIu16".%"PRIu16, + major_version, + minor_version, + lfs_fs_disk_version_major(lfs), + lfs_fs_disk_version_minor(lfs)); + err = LFS_ERR_INVAL; + goto cleanup; + } + + // found older minor version? set an in-device only bit in the + // gstate so we know we need to rewrite the superblock before + // the first write + if (minor_version < lfs_fs_disk_version_minor(lfs)) { + LFS_DEBUG("Found older minor version " + "v%"PRIu16".%"PRIu16" < v%"PRIu16".%"PRIu16, + major_version, + minor_version, + lfs_fs_disk_version_major(lfs), + lfs_fs_disk_version_minor(lfs)); + // note this bit is reserved on disk, so fetching more gstate + // will not interfere here + lfs_fs_prepsuperblock(lfs, true); + } + + // check superblock configuration + if (superblock.name_max) { + if (superblock.name_max > lfs->name_max) { + LFS_ERROR("Unsupported name_max (%"PRIu32" > %"PRIu32")", + superblock.name_max, lfs->name_max); + err = LFS_ERR_INVAL; + goto cleanup; + } + + lfs->name_max = superblock.name_max; + } + + if (superblock.file_max) { + if (superblock.file_max > lfs->file_max) { + LFS_ERROR("Unsupported file_max (%"PRIu32" > %"PRIu32")", + superblock.file_max, lfs->file_max); + err = LFS_ERR_INVAL; + goto cleanup; + } + + lfs->file_max = superblock.file_max; + } + + if (superblock.attr_max) { + if (superblock.attr_max > lfs->attr_max) { + LFS_ERROR("Unsupported attr_max (%"PRIu32" > %"PRIu32")", + superblock.attr_max, lfs->attr_max); + err = LFS_ERR_INVAL; + goto cleanup; + } + + lfs->attr_max = superblock.attr_max; + + // we also need to update inline_max in case attr_max changed + lfs->inline_max = lfs_min(lfs->inline_max, lfs->attr_max); + } + + // this is where we get the block_count from disk if block_count=0 + if (lfs->cfg->block_count + && superblock.block_count != lfs->cfg->block_count) { + LFS_ERROR("Invalid block count (%"PRIu32" != %"PRIu32")", + superblock.block_count, lfs->cfg->block_count); + err = LFS_ERR_INVAL; + goto cleanup; + } + + lfs->block_count = superblock.block_count; + + if (superblock.block_size != lfs->cfg->block_size) { + LFS_ERROR("Invalid block size (%"PRIu32" != %"PRIu32")", + superblock.block_size, lfs->cfg->block_size); + err = LFS_ERR_INVAL; + goto cleanup; + } + } + + // has gstate? + err = lfs_dir_getgstate(lfs, &dir, &lfs->gstate); + if (err) { + goto cleanup; + } + } + + // update littlefs with gstate + if (!lfs_gstate_iszero(&lfs->gstate)) { + LFS_DEBUG("Found pending gstate 0x%08"PRIx32"%08"PRIx32"%08"PRIx32, + lfs->gstate.tag, + lfs->gstate.pair[0], + lfs->gstate.pair[1]); + } + lfs->gstate.tag += !lfs_tag_isvalid(lfs->gstate.tag); + lfs->gdisk = lfs->gstate; + + // setup free lookahead, to distribute allocations uniformly across + // boots, we start the allocator at a random location + lfs->lookahead.start = lfs->seed % lfs->block_count; + lfs_alloc_drop(lfs); + + return 0; + +cleanup: + lfs_unmount_(lfs); + return err; +} + +static int lfs_unmount_(lfs_t *lfs) { + return lfs_deinit(lfs); +} + + +/// Filesystem filesystem operations /// +static int lfs_fs_stat_(lfs_t *lfs, struct lfs_fsinfo *fsinfo) { + // if the superblock is up-to-date, we must be on the most recent + // minor version of littlefs + if (!lfs_gstate_needssuperblock(&lfs->gstate)) { + fsinfo->disk_version = lfs_fs_disk_version(lfs); + + // otherwise we need to read the minor version on disk + } else { + // fetch the superblock + lfs_mdir_t dir; + int err = lfs_dir_fetch(lfs, &dir, lfs->root); + if (err) { + return err; + } + + lfs_superblock_t superblock; + lfs_stag_t tag = lfs_dir_get(lfs, &dir, LFS_MKTAG(0x7ff, 0x3ff, 0), + LFS_MKTAG(LFS_TYPE_INLINESTRUCT, 0, sizeof(superblock)), + &superblock); + if (tag < 0) { + return tag; + } + lfs_superblock_fromle32(&superblock); + + // read the on-disk version + fsinfo->disk_version = superblock.version; + } + + // filesystem geometry + fsinfo->block_size = lfs->cfg->block_size; + fsinfo->block_count = lfs->block_count; + + // other on-disk configuration, we cache all of these for internal use + fsinfo->name_max = lfs->name_max; + fsinfo->file_max = lfs->file_max; + fsinfo->attr_max = lfs->attr_max; + + return 0; +} + +int lfs_fs_traverse_(lfs_t *lfs, + int (*cb)(void *data, lfs_block_t block), void *data, + bool includeorphans) { + // iterate over metadata pairs + lfs_mdir_t dir = {.tail = {0, 1}}; + +#ifdef LFS_MIGRATE + // also consider v1 blocks during migration + if (lfs->lfs1) { + int err = lfs1_traverse(lfs, cb, data); + if (err) { + return err; + } + + dir.tail[0] = lfs->root[0]; + dir.tail[1] = lfs->root[1]; + } +#endif + + lfs_block_t tortoise[2] = {LFS_BLOCK_NULL, LFS_BLOCK_NULL}; + lfs_size_t tortoise_i = 1; + lfs_size_t tortoise_period = 1; + while (!lfs_pair_isnull(dir.tail)) { + // detect cycles with Brent's algorithm + if (lfs_pair_issync(dir.tail, tortoise)) { + LFS_WARN("Cycle detected in tail list"); + return LFS_ERR_CORRUPT; + } + if (tortoise_i == tortoise_period) { + tortoise[0] = dir.tail[0]; + tortoise[1] = dir.tail[1]; + tortoise_i = 0; + tortoise_period *= 2; + } + tortoise_i += 1; + + for (int i = 0; i < 2; i++) { + int err = cb(data, dir.tail[i]); + if (err) { + return err; + } + } + + // iterate through ids in directory + int err = lfs_dir_fetch(lfs, &dir, dir.tail); + if (err) { + return err; + } + + for (uint16_t id = 0; id < dir.count; id++) { + struct lfs_ctz ctz; + lfs_stag_t tag = lfs_dir_get(lfs, &dir, LFS_MKTAG(0x700, 0x3ff, 0), + LFS_MKTAG(LFS_TYPE_STRUCT, id, sizeof(ctz)), &ctz); + if (tag < 0) { + if (tag == LFS_ERR_NOENT) { + continue; + } + return tag; + } + lfs_ctz_fromle32(&ctz); + + if (lfs_tag_type3(tag) == LFS_TYPE_CTZSTRUCT) { + err = lfs_ctz_traverse(lfs, NULL, &lfs->rcache, + ctz.head, ctz.size, cb, data); + if (err) { + return err; + } + } else if (includeorphans && + lfs_tag_type3(tag) == LFS_TYPE_DIRSTRUCT) { + for (int i = 0; i < 2; i++) { + err = cb(data, (&ctz.head)[i]); + if (err) { + return err; + } + } + } + } + } + +#ifndef LFS_READONLY + // iterate over any open files + for (lfs_file_t *f = (lfs_file_t*)lfs->mlist; f; f = f->next) { + if (f->type != LFS_TYPE_REG) { + continue; + } + + if ((f->flags & LFS_F_DIRTY) && !(f->flags & LFS_F_INLINE)) { + int err = lfs_ctz_traverse(lfs, &f->cache, &lfs->rcache, + f->ctz.head, f->ctz.size, cb, data); + if (err) { + return err; + } + } + + if ((f->flags & LFS_F_WRITING) && !(f->flags & LFS_F_INLINE)) { + int err = lfs_ctz_traverse(lfs, &f->cache, &lfs->rcache, + f->block, f->pos, cb, data); + if (err) { + return err; + } + } + } +#endif + + return 0; +} + +#ifndef LFS_READONLY +static int lfs_fs_pred(lfs_t *lfs, + const lfs_block_t pair[2], lfs_mdir_t *pdir) { + // iterate over all directory directory entries + pdir->tail[0] = 0; + pdir->tail[1] = 1; + lfs_block_t tortoise[2] = {LFS_BLOCK_NULL, LFS_BLOCK_NULL}; + lfs_size_t tortoise_i = 1; + lfs_size_t tortoise_period = 1; + while (!lfs_pair_isnull(pdir->tail)) { + // detect cycles with Brent's algorithm + if (lfs_pair_issync(pdir->tail, tortoise)) { + LFS_WARN("Cycle detected in tail list"); + return LFS_ERR_CORRUPT; + } + if (tortoise_i == tortoise_period) { + tortoise[0] = pdir->tail[0]; + tortoise[1] = pdir->tail[1]; + tortoise_i = 0; + tortoise_period *= 2; + } + tortoise_i += 1; + + if (lfs_pair_cmp(pdir->tail, pair) == 0) { + return 0; + } + + int err = lfs_dir_fetch(lfs, pdir, pdir->tail); + if (err) { + return err; + } + } + + return LFS_ERR_NOENT; +} +#endif + +#ifndef LFS_READONLY +struct lfs_fs_parent_match { + lfs_t *lfs; + const lfs_block_t pair[2]; +}; +#endif + +#ifndef LFS_READONLY +static int lfs_fs_parent_match(void *data, + lfs_tag_t tag, const void *buffer) { + struct lfs_fs_parent_match *find = data; + lfs_t *lfs = find->lfs; + const struct lfs_diskoff *disk = buffer; + (void)tag; + + lfs_block_t child[2]; + int err = lfs_bd_read(lfs, + &lfs->pcache, &lfs->rcache, lfs->cfg->block_size, + disk->block, disk->off, &child, sizeof(child)); + if (err) { + return err; + } + + lfs_pair_fromle32(child); + return (lfs_pair_cmp(child, find->pair) == 0) ? LFS_CMP_EQ : LFS_CMP_LT; +} +#endif + +#ifndef LFS_READONLY +static lfs_stag_t lfs_fs_parent(lfs_t *lfs, const lfs_block_t pair[2], + lfs_mdir_t *parent) { + // use fetchmatch with callback to find pairs + parent->tail[0] = 0; + parent->tail[1] = 1; + lfs_block_t tortoise[2] = {LFS_BLOCK_NULL, LFS_BLOCK_NULL}; + lfs_size_t tortoise_i = 1; + lfs_size_t tortoise_period = 1; + while (!lfs_pair_isnull(parent->tail)) { + // detect cycles with Brent's algorithm + if (lfs_pair_issync(parent->tail, tortoise)) { + LFS_WARN("Cycle detected in tail list"); + return LFS_ERR_CORRUPT; + } + if (tortoise_i == tortoise_period) { + tortoise[0] = parent->tail[0]; + tortoise[1] = parent->tail[1]; + tortoise_i = 0; + tortoise_period *= 2; + } + tortoise_i += 1; + + lfs_stag_t tag = lfs_dir_fetchmatch(lfs, parent, parent->tail, + LFS_MKTAG(0x7ff, 0, 0x3ff), + LFS_MKTAG(LFS_TYPE_DIRSTRUCT, 0, 8), + NULL, + lfs_fs_parent_match, &(struct lfs_fs_parent_match){ + lfs, {pair[0], pair[1]}}); + if (tag && tag != LFS_ERR_NOENT) { + return tag; + } + } + + return LFS_ERR_NOENT; +} +#endif + +static void lfs_fs_prepsuperblock(lfs_t *lfs, bool needssuperblock) { + lfs->gstate.tag = (lfs->gstate.tag & ~LFS_MKTAG(0, 0, 0x200)) + | (uint32_t)needssuperblock << 9; +} + +#ifndef LFS_READONLY +static int lfs_fs_preporphans(lfs_t *lfs, int8_t orphans) { + LFS_ASSERT(lfs_tag_size(lfs->gstate.tag) > 0x000 || orphans >= 0); + LFS_ASSERT(lfs_tag_size(lfs->gstate.tag) < 0x1ff || orphans <= 0); + lfs->gstate.tag += orphans; + lfs->gstate.tag = ((lfs->gstate.tag & ~LFS_MKTAG(0x800, 0, 0)) | + ((uint32_t)lfs_gstate_hasorphans(&lfs->gstate) << 31)); + + return 0; +} +#endif + +#ifndef LFS_READONLY +static void lfs_fs_prepmove(lfs_t *lfs, + uint16_t id, const lfs_block_t pair[2]) { + lfs->gstate.tag = ((lfs->gstate.tag & ~LFS_MKTAG(0x7ff, 0x3ff, 0)) | + ((id != 0x3ff) ? LFS_MKTAG(LFS_TYPE_DELETE, id, 0) : 0)); + lfs->gstate.pair[0] = (id != 0x3ff) ? pair[0] : 0; + lfs->gstate.pair[1] = (id != 0x3ff) ? pair[1] : 0; +} +#endif + +#ifndef LFS_READONLY +static int lfs_fs_desuperblock(lfs_t *lfs) { + if (!lfs_gstate_needssuperblock(&lfs->gstate)) { + return 0; + } + + LFS_DEBUG("Rewriting superblock {0x%"PRIx32", 0x%"PRIx32"}", + lfs->root[0], + lfs->root[1]); + + lfs_mdir_t root; + int err = lfs_dir_fetch(lfs, &root, lfs->root); + if (err) { + return err; + } + + // write a new superblock + lfs_superblock_t superblock = { + .version = lfs_fs_disk_version(lfs), + .block_size = lfs->cfg->block_size, + .block_count = lfs->block_count, + .name_max = lfs->name_max, + .file_max = lfs->file_max, + .attr_max = lfs->attr_max, + }; + + lfs_superblock_tole32(&superblock); + err = lfs_dir_commit(lfs, &root, LFS_MKATTRS( + {LFS_MKTAG(LFS_TYPE_INLINESTRUCT, 0, sizeof(superblock)), + &superblock})); + if (err) { + return err; + } + + lfs_fs_prepsuperblock(lfs, false); + return 0; +} +#endif + +#ifndef LFS_READONLY +static int lfs_fs_demove(lfs_t *lfs) { + if (!lfs_gstate_hasmove(&lfs->gdisk)) { + return 0; + } + + // Fix bad moves + LFS_DEBUG("Fixing move {0x%"PRIx32", 0x%"PRIx32"} 0x%"PRIx16, + lfs->gdisk.pair[0], + lfs->gdisk.pair[1], + lfs_tag_id(lfs->gdisk.tag)); + + // no other gstate is supported at this time, so if we found something else + // something most likely went wrong in gstate calculation + LFS_ASSERT(lfs_tag_type3(lfs->gdisk.tag) == LFS_TYPE_DELETE); + + // fetch and delete the moved entry + lfs_mdir_t movedir; + int err = lfs_dir_fetch(lfs, &movedir, lfs->gdisk.pair); + if (err) { + return err; + } + + // prep gstate and delete move id + uint16_t moveid = lfs_tag_id(lfs->gdisk.tag); + lfs_fs_prepmove(lfs, 0x3ff, NULL); + err = lfs_dir_commit(lfs, &movedir, LFS_MKATTRS( + {LFS_MKTAG(LFS_TYPE_DELETE, moveid, 0), NULL})); + if (err) { + return err; + } + + return 0; +} +#endif + +#ifndef LFS_READONLY +static int lfs_fs_deorphan(lfs_t *lfs, bool powerloss) { + if (!lfs_gstate_hasorphans(&lfs->gstate)) { + return 0; + } + + // Check for orphans in two separate passes: + // - 1 for half-orphans (relocations) + // - 2 for full-orphans (removes/renames) + // + // Two separate passes are needed as half-orphans can contain outdated + // references to full-orphans, effectively hiding them from the deorphan + // search. + // + int pass = 0; + while (pass < 2) { + // Fix any orphans + lfs_mdir_t pdir = {.split = true, .tail = {0, 1}}; + lfs_mdir_t dir; + bool moreorphans = false; + + // iterate over all directory directory entries + while (!lfs_pair_isnull(pdir.tail)) { + int err = lfs_dir_fetch(lfs, &dir, pdir.tail); + if (err) { + return err; + } + + // check head blocks for orphans + if (!pdir.split) { + // check if we have a parent + lfs_mdir_t parent; + lfs_stag_t tag = lfs_fs_parent(lfs, pdir.tail, &parent); + if (tag < 0 && tag != LFS_ERR_NOENT) { + return tag; + } + + if (pass == 0 && tag != LFS_ERR_NOENT) { + lfs_block_t pair[2]; + lfs_stag_t state = lfs_dir_get(lfs, &parent, + LFS_MKTAG(0x7ff, 0x3ff, 0), tag, pair); + if (state < 0) { + return state; + } + lfs_pair_fromle32(pair); + + if (!lfs_pair_issync(pair, pdir.tail)) { + // we have desynced + LFS_DEBUG("Fixing half-orphan " + "{0x%"PRIx32", 0x%"PRIx32"} " + "-> {0x%"PRIx32", 0x%"PRIx32"}", + pdir.tail[0], pdir.tail[1], pair[0], pair[1]); + + // fix pending move in this pair? this looks like an + // optimization but is in fact _required_ since + // relocating may outdate the move. + uint16_t moveid = 0x3ff; + if (lfs_gstate_hasmovehere(&lfs->gstate, pdir.pair)) { + moveid = lfs_tag_id(lfs->gstate.tag); + LFS_DEBUG("Fixing move while fixing orphans " + "{0x%"PRIx32", 0x%"PRIx32"} 0x%"PRIx16"\n", + pdir.pair[0], pdir.pair[1], moveid); + lfs_fs_prepmove(lfs, 0x3ff, NULL); + } + + lfs_pair_tole32(pair); + state = lfs_dir_orphaningcommit(lfs, &pdir, LFS_MKATTRS( + {LFS_MKTAG_IF(moveid != 0x3ff, + LFS_TYPE_DELETE, moveid, 0), NULL}, + {LFS_MKTAG(LFS_TYPE_SOFTTAIL, 0x3ff, 8), + pair})); + lfs_pair_fromle32(pair); + if (state < 0) { + return state; + } + + // did our commit create more orphans? + if (state == LFS_OK_ORPHANED) { + moreorphans = true; + } + + // refetch tail + continue; + } + } + + // note we only check for full orphans if we may have had a + // power-loss, otherwise orphans are created intentionally + // during operations such as lfs_mkdir + if (pass == 1 && tag == LFS_ERR_NOENT && powerloss) { + // we are an orphan + LFS_DEBUG("Fixing orphan {0x%"PRIx32", 0x%"PRIx32"}", + pdir.tail[0], pdir.tail[1]); + + // steal state + err = lfs_dir_getgstate(lfs, &dir, &lfs->gdelta); + if (err) { + return err; + } + + // steal tail + lfs_pair_tole32(dir.tail); + int state = lfs_dir_orphaningcommit(lfs, &pdir, LFS_MKATTRS( + {LFS_MKTAG(LFS_TYPE_TAIL + dir.split, 0x3ff, 8), + dir.tail})); + lfs_pair_fromle32(dir.tail); + if (state < 0) { + return state; + } + + // did our commit create more orphans? + if (state == LFS_OK_ORPHANED) { + moreorphans = true; + } + + // refetch tail + continue; + } + } + + pdir = dir; + } + + pass = moreorphans ? 0 : pass+1; + } + + // mark orphans as fixed + return lfs_fs_preporphans(lfs, -lfs_gstate_getorphans(&lfs->gstate)); +} +#endif + +#ifndef LFS_READONLY +static int lfs_fs_forceconsistency(lfs_t *lfs) { + int err = lfs_fs_desuperblock(lfs); + if (err) { + return err; + } + + err = lfs_fs_demove(lfs); + if (err) { + return err; + } + + err = lfs_fs_deorphan(lfs, true); + if (err) { + return err; + } + + return 0; +} +#endif + +#ifndef LFS_READONLY +static int lfs_fs_mkconsistent_(lfs_t *lfs) { + // lfs_fs_forceconsistency does most of the work here + int err = lfs_fs_forceconsistency(lfs); + if (err) { + return err; + } + + // do we have any pending gstate? + lfs_gstate_t delta = {0}; + lfs_gstate_xor(&delta, &lfs->gdisk); + lfs_gstate_xor(&delta, &lfs->gstate); + if (!lfs_gstate_iszero(&delta)) { + // lfs_dir_commit will implicitly write out any pending gstate + lfs_mdir_t root; + err = lfs_dir_fetch(lfs, &root, lfs->root); + if (err) { + return err; + } + + err = lfs_dir_commit(lfs, &root, NULL, 0); + if (err) { + return err; + } + } + + return 0; +} +#endif + +static int lfs_fs_size_count(void *p, lfs_block_t block) { + (void)block; + lfs_size_t *size = p; + *size += 1; + return 0; +} + +static lfs_ssize_t lfs_fs_size_(lfs_t *lfs) { + lfs_size_t size = 0; + int err = lfs_fs_traverse_(lfs, lfs_fs_size_count, &size, false); + if (err) { + return err; + } + + return size; +} + +// explicit garbage collection +#ifndef LFS_READONLY +static int lfs_fs_gc_(lfs_t *lfs) { + // force consistency, even if we're not necessarily going to write, + // because this function is supposed to take care of janitorial work + // isn't it? + int err = lfs_fs_forceconsistency(lfs); + if (err) { + return err; + } + + // try to compact metadata pairs, note we can't really accomplish + // anything if compact_thresh doesn't at least leave a prog_size + // available + if (lfs->cfg->compact_thresh + < lfs->cfg->block_size - lfs->cfg->prog_size) { + // iterate over all mdirs + lfs_mdir_t mdir = {.tail = {0, 1}}; + while (!lfs_pair_isnull(mdir.tail)) { + err = lfs_dir_fetch(lfs, &mdir, mdir.tail); + if (err) { + return err; + } + + // not erased? exceeds our compaction threshold? + if (!mdir.erased || ((lfs->cfg->compact_thresh == 0) + ? mdir.off > lfs->cfg->block_size - lfs->cfg->block_size/8 + : mdir.off > lfs->cfg->compact_thresh)) { + // the easiest way to trigger a compaction is to mark + // the mdir as unerased and add an empty commit + mdir.erased = false; + err = lfs_dir_commit(lfs, &mdir, NULL, 0); + if (err) { + return err; + } + } + } + } + + // try to populate the lookahead buffer, unless it's already full + if (lfs->lookahead.size < 8*lfs->cfg->lookahead_size) { + err = lfs_alloc_scan(lfs); + if (err) { + return err; + } + } + + return 0; +} +#endif + +#ifndef LFS_READONLY +static int lfs_fs_grow_(lfs_t *lfs, lfs_size_t block_count) { + // shrinking is not supported + LFS_ASSERT(block_count >= lfs->block_count); + + if (block_count > lfs->block_count) { + lfs->block_count = block_count; + + // fetch the root + lfs_mdir_t root; + int err = lfs_dir_fetch(lfs, &root, lfs->root); + if (err) { + return err; + } + + // update the superblock + lfs_superblock_t superblock; + lfs_stag_t tag = lfs_dir_get(lfs, &root, LFS_MKTAG(0x7ff, 0x3ff, 0), + LFS_MKTAG(LFS_TYPE_INLINESTRUCT, 0, sizeof(superblock)), + &superblock); + if (tag < 0) { + return tag; + } + lfs_superblock_fromle32(&superblock); + + superblock.block_count = lfs->block_count; + + lfs_superblock_tole32(&superblock); + err = lfs_dir_commit(lfs, &root, LFS_MKATTRS( + {tag, &superblock})); + if (err) { + return err; + } + } + + return 0; +} +#endif + +#ifdef LFS_MIGRATE +////// Migration from littelfs v1 below this ////// + +/// Version info /// + +// Software library version +// Major (top-nibble), incremented on backwards incompatible changes +// Minor (bottom-nibble), incremented on feature additions +#define LFS1_VERSION 0x00010007 +#define LFS1_VERSION_MAJOR (0xffff & (LFS1_VERSION >> 16)) +#define LFS1_VERSION_MINOR (0xffff & (LFS1_VERSION >> 0)) + +// Version of On-disk data structures +// Major (top-nibble), incremented on backwards incompatible changes +// Minor (bottom-nibble), incremented on feature additions +#define LFS1_DISK_VERSION 0x00010001 +#define LFS1_DISK_VERSION_MAJOR (0xffff & (LFS1_DISK_VERSION >> 16)) +#define LFS1_DISK_VERSION_MINOR (0xffff & (LFS1_DISK_VERSION >> 0)) + + +/// v1 Definitions /// + +// File types +enum lfs1_type { + LFS1_TYPE_REG = 0x11, + LFS1_TYPE_DIR = 0x22, + LFS1_TYPE_SUPERBLOCK = 0x2e, +}; + +typedef struct lfs1 { + lfs_block_t root[2]; +} lfs1_t; + +typedef struct lfs1_entry { + lfs_off_t off; + + struct lfs1_disk_entry { + uint8_t type; + uint8_t elen; + uint8_t alen; + uint8_t nlen; + union { + struct { + lfs_block_t head; + lfs_size_t size; + } file; + lfs_block_t dir[2]; + } u; + } d; +} lfs1_entry_t; + +typedef struct lfs1_dir { + struct lfs1_dir *next; + lfs_block_t pair[2]; + lfs_off_t off; + + lfs_block_t head[2]; + lfs_off_t pos; + + struct lfs1_disk_dir { + uint32_t rev; + lfs_size_t size; + lfs_block_t tail[2]; + } d; +} lfs1_dir_t; + +typedef struct lfs1_superblock { + lfs_off_t off; + + struct lfs1_disk_superblock { + uint8_t type; + uint8_t elen; + uint8_t alen; + uint8_t nlen; + lfs_block_t root[2]; + uint32_t block_size; + uint32_t block_count; + uint32_t version; + char magic[8]; + } d; +} lfs1_superblock_t; + + +/// Low-level wrappers v1->v2 /// +static void lfs1_crc(uint32_t *crc, const void *buffer, size_t size) { + *crc = lfs_crc(*crc, buffer, size); +} + +static int lfs1_bd_read(lfs_t *lfs, lfs_block_t block, + lfs_off_t off, void *buffer, lfs_size_t size) { + // if we ever do more than writes to alternating pairs, + // this may need to consider pcache + return lfs_bd_read(lfs, &lfs->pcache, &lfs->rcache, size, + block, off, buffer, size); +} + +static int lfs1_bd_crc(lfs_t *lfs, lfs_block_t block, + lfs_off_t off, lfs_size_t size, uint32_t *crc) { + for (lfs_off_t i = 0; i < size; i++) { + uint8_t c; + int err = lfs1_bd_read(lfs, block, off+i, &c, 1); + if (err) { + return err; + } + + lfs1_crc(crc, &c, 1); + } + + return 0; +} + + +/// Endian swapping functions /// +static void lfs1_dir_fromle32(struct lfs1_disk_dir *d) { + d->rev = lfs_fromle32(d->rev); + d->size = lfs_fromle32(d->size); + d->tail[0] = lfs_fromle32(d->tail[0]); + d->tail[1] = lfs_fromle32(d->tail[1]); +} + +static void lfs1_dir_tole32(struct lfs1_disk_dir *d) { + d->rev = lfs_tole32(d->rev); + d->size = lfs_tole32(d->size); + d->tail[0] = lfs_tole32(d->tail[0]); + d->tail[1] = lfs_tole32(d->tail[1]); +} + +static void lfs1_entry_fromle32(struct lfs1_disk_entry *d) { + d->u.dir[0] = lfs_fromle32(d->u.dir[0]); + d->u.dir[1] = lfs_fromle32(d->u.dir[1]); +} + +static void lfs1_entry_tole32(struct lfs1_disk_entry *d) { + d->u.dir[0] = lfs_tole32(d->u.dir[0]); + d->u.dir[1] = lfs_tole32(d->u.dir[1]); +} + +static void lfs1_superblock_fromle32(struct lfs1_disk_superblock *d) { + d->root[0] = lfs_fromle32(d->root[0]); + d->root[1] = lfs_fromle32(d->root[1]); + d->block_size = lfs_fromle32(d->block_size); + d->block_count = lfs_fromle32(d->block_count); + d->version = lfs_fromle32(d->version); +} + + +///// Metadata pair and directory operations /// +static inline lfs_size_t lfs1_entry_size(const lfs1_entry_t *entry) { + return 4 + entry->d.elen + entry->d.alen + entry->d.nlen; +} + +static int lfs1_dir_fetch(lfs_t *lfs, + lfs1_dir_t *dir, const lfs_block_t pair[2]) { + // copy out pair, otherwise may be aliasing dir + const lfs_block_t tpair[2] = {pair[0], pair[1]}; + bool valid = false; + + // check both blocks for the most recent revision + for (int i = 0; i < 2; i++) { + struct lfs1_disk_dir test; + int err = lfs1_bd_read(lfs, tpair[i], 0, &test, sizeof(test)); + lfs1_dir_fromle32(&test); + if (err) { + if (err == LFS_ERR_CORRUPT) { + continue; + } + return err; + } + + if (valid && lfs_scmp(test.rev, dir->d.rev) < 0) { + continue; + } + + if ((0x7fffffff & test.size) < sizeof(test)+4 || + (0x7fffffff & test.size) > lfs->cfg->block_size) { + continue; + } + + uint32_t crc = 0xffffffff; + lfs1_dir_tole32(&test); + lfs1_crc(&crc, &test, sizeof(test)); + lfs1_dir_fromle32(&test); + err = lfs1_bd_crc(lfs, tpair[i], sizeof(test), + (0x7fffffff & test.size) - sizeof(test), &crc); + if (err) { + if (err == LFS_ERR_CORRUPT) { + continue; + } + return err; + } + + if (crc != 0) { + continue; + } + + valid = true; + + // setup dir in case it's valid + dir->pair[0] = tpair[(i+0) % 2]; + dir->pair[1] = tpair[(i+1) % 2]; + dir->off = sizeof(dir->d); + dir->d = test; + } + + if (!valid) { + LFS_ERROR("Corrupted dir pair at {0x%"PRIx32", 0x%"PRIx32"}", + tpair[0], tpair[1]); + return LFS_ERR_CORRUPT; + } + + return 0; +} + +static int lfs1_dir_next(lfs_t *lfs, lfs1_dir_t *dir, lfs1_entry_t *entry) { + while (dir->off + sizeof(entry->d) > (0x7fffffff & dir->d.size)-4) { + if (!(0x80000000 & dir->d.size)) { + entry->off = dir->off; + return LFS_ERR_NOENT; + } + + int err = lfs1_dir_fetch(lfs, dir, dir->d.tail); + if (err) { + return err; + } + + dir->off = sizeof(dir->d); + dir->pos += sizeof(dir->d) + 4; + } + + int err = lfs1_bd_read(lfs, dir->pair[0], dir->off, + &entry->d, sizeof(entry->d)); + lfs1_entry_fromle32(&entry->d); + if (err) { + return err; + } + + entry->off = dir->off; + dir->off += lfs1_entry_size(entry); + dir->pos += lfs1_entry_size(entry); + return 0; +} + +/// littlefs v1 specific operations /// +int lfs1_traverse(lfs_t *lfs, int (*cb)(void*, lfs_block_t), void *data) { + if (lfs_pair_isnull(lfs->lfs1->root)) { + return 0; + } + + // iterate over metadata pairs + lfs1_dir_t dir; + lfs1_entry_t entry; + lfs_block_t cwd[2] = {0, 1}; + + while (true) { + for (int i = 0; i < 2; i++) { + int err = cb(data, cwd[i]); + if (err) { + return err; + } + } + + int err = lfs1_dir_fetch(lfs, &dir, cwd); + if (err) { + return err; + } + + // iterate over contents + while (dir.off + sizeof(entry.d) <= (0x7fffffff & dir.d.size)-4) { + err = lfs1_bd_read(lfs, dir.pair[0], dir.off, + &entry.d, sizeof(entry.d)); + lfs1_entry_fromle32(&entry.d); + if (err) { + return err; + } + + dir.off += lfs1_entry_size(&entry); + if ((0x70 & entry.d.type) == (0x70 & LFS1_TYPE_REG)) { + err = lfs_ctz_traverse(lfs, NULL, &lfs->rcache, + entry.d.u.file.head, entry.d.u.file.size, cb, data); + if (err) { + return err; + } + } + } + + // we also need to check if we contain a threaded v2 directory + lfs_mdir_t dir2 = {.split=true, .tail={cwd[0], cwd[1]}}; + while (dir2.split) { + err = lfs_dir_fetch(lfs, &dir2, dir2.tail); + if (err) { + break; + } + + for (int i = 0; i < 2; i++) { + err = cb(data, dir2.pair[i]); + if (err) { + return err; + } + } + } + + cwd[0] = dir.d.tail[0]; + cwd[1] = dir.d.tail[1]; + + if (lfs_pair_isnull(cwd)) { + break; + } + } + + return 0; +} + +static int lfs1_moved(lfs_t *lfs, const void *e) { + if (lfs_pair_isnull(lfs->lfs1->root)) { + return 0; + } + + // skip superblock + lfs1_dir_t cwd; + int err = lfs1_dir_fetch(lfs, &cwd, (const lfs_block_t[2]){0, 1}); + if (err) { + return err; + } + + // iterate over all directory directory entries + lfs1_entry_t entry; + while (!lfs_pair_isnull(cwd.d.tail)) { + err = lfs1_dir_fetch(lfs, &cwd, cwd.d.tail); + if (err) { + return err; + } + + while (true) { + err = lfs1_dir_next(lfs, &cwd, &entry); + if (err && err != LFS_ERR_NOENT) { + return err; + } + + if (err == LFS_ERR_NOENT) { + break; + } + + if (!(0x80 & entry.d.type) && + memcmp(&entry.d.u, e, sizeof(entry.d.u)) == 0) { + return true; + } + } + } + + return false; +} + +/// Filesystem operations /// +static int lfs1_mount(lfs_t *lfs, struct lfs1 *lfs1, + const struct lfs_config *cfg) { + int err = 0; + { + err = lfs_init(lfs, cfg); + if (err) { + return err; + } + + lfs->lfs1 = lfs1; + lfs->lfs1->root[0] = LFS_BLOCK_NULL; + lfs->lfs1->root[1] = LFS_BLOCK_NULL; + + // setup free lookahead + lfs->lookahead.start = 0; + lfs->lookahead.size = 0; + lfs->lookahead.next = 0; + lfs_alloc_ckpoint(lfs); + + // load superblock + lfs1_dir_t dir; + lfs1_superblock_t superblock; + err = lfs1_dir_fetch(lfs, &dir, (const lfs_block_t[2]){0, 1}); + if (err && err != LFS_ERR_CORRUPT) { + goto cleanup; + } + + if (!err) { + err = lfs1_bd_read(lfs, dir.pair[0], sizeof(dir.d), + &superblock.d, sizeof(superblock.d)); + lfs1_superblock_fromle32(&superblock.d); + if (err) { + goto cleanup; + } + + lfs->lfs1->root[0] = superblock.d.root[0]; + lfs->lfs1->root[1] = superblock.d.root[1]; + } + + if (err || memcmp(superblock.d.magic, "littlefs", 8) != 0) { + LFS_ERROR("Invalid superblock at {0x%"PRIx32", 0x%"PRIx32"}", + 0, 1); + err = LFS_ERR_CORRUPT; + goto cleanup; + } + + uint16_t major_version = (0xffff & (superblock.d.version >> 16)); + uint16_t minor_version = (0xffff & (superblock.d.version >> 0)); + if ((major_version != LFS1_DISK_VERSION_MAJOR || + minor_version > LFS1_DISK_VERSION_MINOR)) { + LFS_ERROR("Invalid version v%d.%d", major_version, minor_version); + err = LFS_ERR_INVAL; + goto cleanup; + } + + return 0; + } + +cleanup: + lfs_deinit(lfs); + return err; +} + +static int lfs1_unmount(lfs_t *lfs) { + return lfs_deinit(lfs); +} + +/// v1 migration /// +static int lfs_migrate_(lfs_t *lfs, const struct lfs_config *cfg) { + struct lfs1 lfs1; + + // Indeterminate filesystem size not allowed for migration. + LFS_ASSERT(cfg->block_count != 0); + + int err = lfs1_mount(lfs, &lfs1, cfg); + if (err) { + return err; + } + + { + // iterate through each directory, copying over entries + // into new directory + lfs1_dir_t dir1; + lfs_mdir_t dir2; + dir1.d.tail[0] = lfs->lfs1->root[0]; + dir1.d.tail[1] = lfs->lfs1->root[1]; + while (!lfs_pair_isnull(dir1.d.tail)) { + // iterate old dir + err = lfs1_dir_fetch(lfs, &dir1, dir1.d.tail); + if (err) { + goto cleanup; + } + + // create new dir and bind as temporary pretend root + err = lfs_dir_alloc(lfs, &dir2); + if (err) { + goto cleanup; + } + + dir2.rev = dir1.d.rev; + dir1.head[0] = dir1.pair[0]; + dir1.head[1] = dir1.pair[1]; + lfs->root[0] = dir2.pair[0]; + lfs->root[1] = dir2.pair[1]; + + err = lfs_dir_commit(lfs, &dir2, NULL, 0); + if (err) { + goto cleanup; + } + + while (true) { + lfs1_entry_t entry1; + err = lfs1_dir_next(lfs, &dir1, &entry1); + if (err && err != LFS_ERR_NOENT) { + goto cleanup; + } + + if (err == LFS_ERR_NOENT) { + break; + } + + // check that entry has not been moved + if (entry1.d.type & 0x80) { + int moved = lfs1_moved(lfs, &entry1.d.u); + if (moved < 0) { + err = moved; + goto cleanup; + } + + if (moved) { + continue; + } + + entry1.d.type &= ~0x80; + } + + // also fetch name + char name[LFS_NAME_MAX+1]; + memset(name, 0, sizeof(name)); + err = lfs1_bd_read(lfs, dir1.pair[0], + entry1.off + 4+entry1.d.elen+entry1.d.alen, + name, entry1.d.nlen); + if (err) { + goto cleanup; + } + + bool isdir = (entry1.d.type == LFS1_TYPE_DIR); + + // create entry in new dir + err = lfs_dir_fetch(lfs, &dir2, lfs->root); + if (err) { + goto cleanup; + } + + uint16_t id; + err = lfs_dir_find(lfs, &dir2, &(const char*){name}, &id); + if (!(err == LFS_ERR_NOENT && id != 0x3ff)) { + err = (err < 0) ? err : LFS_ERR_EXIST; + goto cleanup; + } + + lfs1_entry_tole32(&entry1.d); + err = lfs_dir_commit(lfs, &dir2, LFS_MKATTRS( + {LFS_MKTAG(LFS_TYPE_CREATE, id, 0), NULL}, + {LFS_MKTAG_IF_ELSE(isdir, + LFS_TYPE_DIR, id, entry1.d.nlen, + LFS_TYPE_REG, id, entry1.d.nlen), + name}, + {LFS_MKTAG_IF_ELSE(isdir, + LFS_TYPE_DIRSTRUCT, id, sizeof(entry1.d.u), + LFS_TYPE_CTZSTRUCT, id, sizeof(entry1.d.u)), + &entry1.d.u})); + lfs1_entry_fromle32(&entry1.d); + if (err) { + goto cleanup; + } + } + + if (!lfs_pair_isnull(dir1.d.tail)) { + // find last block and update tail to thread into fs + err = lfs_dir_fetch(lfs, &dir2, lfs->root); + if (err) { + goto cleanup; + } + + while (dir2.split) { + err = lfs_dir_fetch(lfs, &dir2, dir2.tail); + if (err) { + goto cleanup; + } + } + + lfs_pair_tole32(dir2.pair); + err = lfs_dir_commit(lfs, &dir2, LFS_MKATTRS( + {LFS_MKTAG(LFS_TYPE_SOFTTAIL, 0x3ff, 8), dir1.d.tail})); + lfs_pair_fromle32(dir2.pair); + if (err) { + goto cleanup; + } + } + + // Copy over first block to thread into fs. Unfortunately + // if this fails there is not much we can do. + LFS_DEBUG("Migrating {0x%"PRIx32", 0x%"PRIx32"} " + "-> {0x%"PRIx32", 0x%"PRIx32"}", + lfs->root[0], lfs->root[1], dir1.head[0], dir1.head[1]); + + err = lfs_bd_erase(lfs, dir1.head[1]); + if (err) { + goto cleanup; + } + + err = lfs_dir_fetch(lfs, &dir2, lfs->root); + if (err) { + goto cleanup; + } + + for (lfs_off_t i = 0; i < dir2.off; i++) { + uint8_t dat; + err = lfs_bd_read(lfs, + NULL, &lfs->rcache, dir2.off, + dir2.pair[0], i, &dat, 1); + if (err) { + goto cleanup; + } + + err = lfs_bd_prog(lfs, + &lfs->pcache, &lfs->rcache, true, + dir1.head[1], i, &dat, 1); + if (err) { + goto cleanup; + } + } + + err = lfs_bd_flush(lfs, &lfs->pcache, &lfs->rcache, true); + if (err) { + goto cleanup; + } + } + + // Create new superblock. This marks a successful migration! + err = lfs1_dir_fetch(lfs, &dir1, (const lfs_block_t[2]){0, 1}); + if (err) { + goto cleanup; + } + + dir2.pair[0] = dir1.pair[0]; + dir2.pair[1] = dir1.pair[1]; + dir2.rev = dir1.d.rev; + dir2.off = sizeof(dir2.rev); + dir2.etag = 0xffffffff; + dir2.count = 0; + dir2.tail[0] = lfs->lfs1->root[0]; + dir2.tail[1] = lfs->lfs1->root[1]; + dir2.erased = false; + dir2.split = true; + + lfs_superblock_t superblock = { + .version = LFS_DISK_VERSION, + .block_size = lfs->cfg->block_size, + .block_count = lfs->cfg->block_count, + .name_max = lfs->name_max, + .file_max = lfs->file_max, + .attr_max = lfs->attr_max, + }; + + lfs_superblock_tole32(&superblock); + err = lfs_dir_commit(lfs, &dir2, LFS_MKATTRS( + {LFS_MKTAG(LFS_TYPE_CREATE, 0, 0), NULL}, + {LFS_MKTAG(LFS_TYPE_SUPERBLOCK, 0, 8), "littlefs"}, + {LFS_MKTAG(LFS_TYPE_INLINESTRUCT, 0, sizeof(superblock)), + &superblock})); + if (err) { + goto cleanup; + } + + // sanity check that fetch works + err = lfs_dir_fetch(lfs, &dir2, (const lfs_block_t[2]){0, 1}); + if (err) { + goto cleanup; + } + + // force compaction to prevent accidentally mounting v1 + dir2.erased = false; + err = lfs_dir_commit(lfs, &dir2, NULL, 0); + if (err) { + goto cleanup; + } + } + +cleanup: + lfs1_unmount(lfs); + return err; +} + +#endif + + +/// Public API wrappers /// + +// Here we can add tracing/thread safety easily + +// Thread-safe wrappers if enabled +#ifdef LFS_THREADSAFE +#define LFS_LOCK(cfg) cfg->lock(cfg) +#define LFS_UNLOCK(cfg) cfg->unlock(cfg) +#else +#define LFS_LOCK(cfg) ((void)cfg, 0) +#define LFS_UNLOCK(cfg) ((void)cfg) +#endif + +// Public API +#ifndef LFS_READONLY +int lfs_format(lfs_t *lfs, const struct lfs_config *cfg) { + int err = LFS_LOCK(cfg); + if (err) { + return err; + } + LFS_TRACE("lfs_format(%p, %p {.context=%p, " + ".read=%p, .prog=%p, .erase=%p, .sync=%p, " + ".read_size=%"PRIu32", .prog_size=%"PRIu32", " + ".block_size=%"PRIu32", .block_count=%"PRIu32", " + ".block_cycles=%"PRIu32", .cache_size=%"PRIu32", " + ".lookahead_size=%"PRIu32", .read_buffer=%p, " + ".prog_buffer=%p, .lookahead_buffer=%p, " + ".name_max=%"PRIu32", .file_max=%"PRIu32", " + ".attr_max=%"PRIu32"})", + (void*)lfs, (void*)cfg, cfg->context, + (void*)(uintptr_t)cfg->read, (void*)(uintptr_t)cfg->prog, + (void*)(uintptr_t)cfg->erase, (void*)(uintptr_t)cfg->sync, + cfg->read_size, cfg->prog_size, cfg->block_size, cfg->block_count, + cfg->block_cycles, cfg->cache_size, cfg->lookahead_size, + cfg->read_buffer, cfg->prog_buffer, cfg->lookahead_buffer, + cfg->name_max, cfg->file_max, cfg->attr_max); + + err = lfs_format_(lfs, cfg); + + LFS_TRACE("lfs_format -> %d", err); + LFS_UNLOCK(cfg); + return err; +} +#endif + +int lfs_mount(lfs_t *lfs, const struct lfs_config *cfg) { + int err = LFS_LOCK(cfg); + if (err) { + return err; + } + LFS_TRACE("lfs_mount(%p, %p {.context=%p, " + ".read=%p, .prog=%p, .erase=%p, .sync=%p, " + ".read_size=%"PRIu32", .prog_size=%"PRIu32", " + ".block_size=%"PRIu32", .block_count=%"PRIu32", " + ".block_cycles=%"PRIu32", .cache_size=%"PRIu32", " + ".lookahead_size=%"PRIu32", .read_buffer=%p, " + ".prog_buffer=%p, .lookahead_buffer=%p, " + ".name_max=%"PRIu32", .file_max=%"PRIu32", " + ".attr_max=%"PRIu32"})", + (void*)lfs, (void*)cfg, cfg->context, + (void*)(uintptr_t)cfg->read, (void*)(uintptr_t)cfg->prog, + (void*)(uintptr_t)cfg->erase, (void*)(uintptr_t)cfg->sync, + cfg->read_size, cfg->prog_size, cfg->block_size, cfg->block_count, + cfg->block_cycles, cfg->cache_size, cfg->lookahead_size, + cfg->read_buffer, cfg->prog_buffer, cfg->lookahead_buffer, + cfg->name_max, cfg->file_max, cfg->attr_max); + + err = lfs_mount_(lfs, cfg); + + LFS_TRACE("lfs_mount -> %d", err); + LFS_UNLOCK(cfg); + return err; +} + +int lfs_unmount(lfs_t *lfs) { + int err = LFS_LOCK(lfs->cfg); + if (err) { + return err; + } + LFS_TRACE("lfs_unmount(%p)", (void*)lfs); + + err = lfs_unmount_(lfs); + + LFS_TRACE("lfs_unmount -> %d", err); + LFS_UNLOCK(lfs->cfg); + return err; +} + +#ifndef LFS_READONLY +int lfs_remove(lfs_t *lfs, const char *path) { + int err = LFS_LOCK(lfs->cfg); + if (err) { + return err; + } + LFS_TRACE("lfs_remove(%p, \"%s\")", (void*)lfs, path); + + err = lfs_remove_(lfs, path); + + LFS_TRACE("lfs_remove -> %d", err); + LFS_UNLOCK(lfs->cfg); + return err; +} +#endif + +#ifndef LFS_READONLY +int lfs_rename(lfs_t *lfs, const char *oldpath, const char *newpath) { + int err = LFS_LOCK(lfs->cfg); + if (err) { + return err; + } + LFS_TRACE("lfs_rename(%p, \"%s\", \"%s\")", (void*)lfs, oldpath, newpath); + + err = lfs_rename_(lfs, oldpath, newpath); + + LFS_TRACE("lfs_rename -> %d", err); + LFS_UNLOCK(lfs->cfg); + return err; +} +#endif + +int lfs_stat(lfs_t *lfs, const char *path, struct lfs_info *info) { + int err = LFS_LOCK(lfs->cfg); + if (err) { + return err; + } + LFS_TRACE("lfs_stat(%p, \"%s\", %p)", (void*)lfs, path, (void*)info); + + err = lfs_stat_(lfs, path, info); + + LFS_TRACE("lfs_stat -> %d", err); + LFS_UNLOCK(lfs->cfg); + return err; +} + +lfs_ssize_t lfs_getattr(lfs_t *lfs, const char *path, + uint8_t type, void *buffer, lfs_size_t size) { + int err = LFS_LOCK(lfs->cfg); + if (err) { + return err; + } + LFS_TRACE("lfs_getattr(%p, \"%s\", %"PRIu8", %p, %"PRIu32")", + (void*)lfs, path, type, buffer, size); + + lfs_ssize_t res = lfs_getattr_(lfs, path, type, buffer, size); + + LFS_TRACE("lfs_getattr -> %"PRId32, res); + LFS_UNLOCK(lfs->cfg); + return res; +} + +#ifndef LFS_READONLY +int lfs_setattr(lfs_t *lfs, const char *path, + uint8_t type, const void *buffer, lfs_size_t size) { + int err = LFS_LOCK(lfs->cfg); + if (err) { + return err; + } + LFS_TRACE("lfs_setattr(%p, \"%s\", %"PRIu8", %p, %"PRIu32")", + (void*)lfs, path, type, buffer, size); + + err = lfs_setattr_(lfs, path, type, buffer, size); + + LFS_TRACE("lfs_setattr -> %d", err); + LFS_UNLOCK(lfs->cfg); + return err; +} +#endif + +#ifndef LFS_READONLY +int lfs_removeattr(lfs_t *lfs, const char *path, uint8_t type) { + int err = LFS_LOCK(lfs->cfg); + if (err) { + return err; + } + LFS_TRACE("lfs_removeattr(%p, \"%s\", %"PRIu8")", (void*)lfs, path, type); + + err = lfs_removeattr_(lfs, path, type); + + LFS_TRACE("lfs_removeattr -> %d", err); + LFS_UNLOCK(lfs->cfg); + return err; +} +#endif + +#ifndef LFS_NO_MALLOC +int lfs_file_open(lfs_t *lfs, lfs_file_t *file, const char *path, int flags) { + int err = LFS_LOCK(lfs->cfg); + if (err) { + return err; + } + LFS_TRACE("lfs_file_open(%p, %p, \"%s\", %x)", + (void*)lfs, (void*)file, path, flags); + LFS_ASSERT(!lfs_mlist_isopen(lfs->mlist, (struct lfs_mlist*)file)); + + err = lfs_file_open_(lfs, file, path, flags); + + LFS_TRACE("lfs_file_open -> %d", err); + LFS_UNLOCK(lfs->cfg); + return err; +} +#endif + +int lfs_file_opencfg(lfs_t *lfs, lfs_file_t *file, + const char *path, int flags, + const struct lfs_file_config *cfg) { + int err = LFS_LOCK(lfs->cfg); + if (err) { + return err; + } + LFS_TRACE("lfs_file_opencfg(%p, %p, \"%s\", %x, %p {" + ".buffer=%p, .attrs=%p, .attr_count=%"PRIu32"})", + (void*)lfs, (void*)file, path, flags, + (void*)cfg, cfg->buffer, (void*)cfg->attrs, cfg->attr_count); + LFS_ASSERT(!lfs_mlist_isopen(lfs->mlist, (struct lfs_mlist*)file)); + + err = lfs_file_opencfg_(lfs, file, path, flags, cfg); + + LFS_TRACE("lfs_file_opencfg -> %d", err); + LFS_UNLOCK(lfs->cfg); + return err; +} + +int lfs_file_close(lfs_t *lfs, lfs_file_t *file) { + int err = LFS_LOCK(lfs->cfg); + if (err) { + return err; + } + LFS_TRACE("lfs_file_close(%p, %p)", (void*)lfs, (void*)file); + LFS_ASSERT(lfs_mlist_isopen(lfs->mlist, (struct lfs_mlist*)file)); + + err = lfs_file_close_(lfs, file); + + LFS_TRACE("lfs_file_close -> %d", err); + LFS_UNLOCK(lfs->cfg); + return err; +} + +#ifndef LFS_READONLY +int lfs_file_sync(lfs_t *lfs, lfs_file_t *file) { + int err = LFS_LOCK(lfs->cfg); + if (err) { + return err; + } + LFS_TRACE("lfs_file_sync(%p, %p)", (void*)lfs, (void*)file); + LFS_ASSERT(lfs_mlist_isopen(lfs->mlist, (struct lfs_mlist*)file)); + + err = lfs_file_sync_(lfs, file); + + LFS_TRACE("lfs_file_sync -> %d", err); + LFS_UNLOCK(lfs->cfg); + return err; +} +#endif + +lfs_ssize_t lfs_file_read(lfs_t *lfs, lfs_file_t *file, + void *buffer, lfs_size_t size) { + int err = LFS_LOCK(lfs->cfg); + if (err) { + return err; + } + LFS_TRACE("lfs_file_read(%p, %p, %p, %"PRIu32")", + (void*)lfs, (void*)file, buffer, size); + LFS_ASSERT(lfs_mlist_isopen(lfs->mlist, (struct lfs_mlist*)file)); + + lfs_ssize_t res = lfs_file_read_(lfs, file, buffer, size); + + LFS_TRACE("lfs_file_read -> %"PRId32, res); + LFS_UNLOCK(lfs->cfg); + return res; +} + +#ifndef LFS_READONLY +lfs_ssize_t lfs_file_write(lfs_t *lfs, lfs_file_t *file, + const void *buffer, lfs_size_t size) { + int err = LFS_LOCK(lfs->cfg); + if (err) { + return err; + } + LFS_TRACE("lfs_file_write(%p, %p, %p, %"PRIu32")", + (void*)lfs, (void*)file, buffer, size); + LFS_ASSERT(lfs_mlist_isopen(lfs->mlist, (struct lfs_mlist*)file)); + + lfs_ssize_t res = lfs_file_write_(lfs, file, buffer, size); + + LFS_TRACE("lfs_file_write -> %"PRId32, res); + LFS_UNLOCK(lfs->cfg); + return res; +} +#endif + +lfs_soff_t lfs_file_seek(lfs_t *lfs, lfs_file_t *file, + lfs_soff_t off, int whence) { + int err = LFS_LOCK(lfs->cfg); + if (err) { + return err; + } + LFS_TRACE("lfs_file_seek(%p, %p, %"PRId32", %d)", + (void*)lfs, (void*)file, off, whence); + LFS_ASSERT(lfs_mlist_isopen(lfs->mlist, (struct lfs_mlist*)file)); + + lfs_soff_t res = lfs_file_seek_(lfs, file, off, whence); + + LFS_TRACE("lfs_file_seek -> %"PRId32, res); + LFS_UNLOCK(lfs->cfg); + return res; +} + +#ifndef LFS_READONLY +int lfs_file_truncate(lfs_t *lfs, lfs_file_t *file, lfs_off_t size) { + int err = LFS_LOCK(lfs->cfg); + if (err) { + return err; + } + LFS_TRACE("lfs_file_truncate(%p, %p, %"PRIu32")", + (void*)lfs, (void*)file, size); + LFS_ASSERT(lfs_mlist_isopen(lfs->mlist, (struct lfs_mlist*)file)); + + err = lfs_file_truncate_(lfs, file, size); + + LFS_TRACE("lfs_file_truncate -> %d", err); + LFS_UNLOCK(lfs->cfg); + return err; +} +#endif + +lfs_soff_t lfs_file_tell(lfs_t *lfs, lfs_file_t *file) { + int err = LFS_LOCK(lfs->cfg); + if (err) { + return err; + } + LFS_TRACE("lfs_file_tell(%p, %p)", (void*)lfs, (void*)file); + LFS_ASSERT(lfs_mlist_isopen(lfs->mlist, (struct lfs_mlist*)file)); + + lfs_soff_t res = lfs_file_tell_(lfs, file); + + LFS_TRACE("lfs_file_tell -> %"PRId32, res); + LFS_UNLOCK(lfs->cfg); + return res; +} + +int lfs_file_rewind(lfs_t *lfs, lfs_file_t *file) { + int err = LFS_LOCK(lfs->cfg); + if (err) { + return err; + } + LFS_TRACE("lfs_file_rewind(%p, %p)", (void*)lfs, (void*)file); + + err = lfs_file_rewind_(lfs, file); + + LFS_TRACE("lfs_file_rewind -> %d", err); + LFS_UNLOCK(lfs->cfg); + return err; +} + +lfs_soff_t lfs_file_size(lfs_t *lfs, lfs_file_t *file) { + int err = LFS_LOCK(lfs->cfg); + if (err) { + return err; + } + LFS_TRACE("lfs_file_size(%p, %p)", (void*)lfs, (void*)file); + LFS_ASSERT(lfs_mlist_isopen(lfs->mlist, (struct lfs_mlist*)file)); + + lfs_soff_t res = lfs_file_size_(lfs, file); + + LFS_TRACE("lfs_file_size -> %"PRId32, res); + LFS_UNLOCK(lfs->cfg); + return res; +} + +#ifndef LFS_READONLY +int lfs_mkdir(lfs_t *lfs, const char *path) { + int err = LFS_LOCK(lfs->cfg); + if (err) { + return err; + } + LFS_TRACE("lfs_mkdir(%p, \"%s\")", (void*)lfs, path); + + err = lfs_mkdir_(lfs, path); + + LFS_TRACE("lfs_mkdir -> %d", err); + LFS_UNLOCK(lfs->cfg); + return err; +} +#endif + +int lfs_dir_open(lfs_t *lfs, lfs_dir_t *dir, const char *path) { + int err = LFS_LOCK(lfs->cfg); + if (err) { + return err; + } + LFS_TRACE("lfs_dir_open(%p, %p, \"%s\")", (void*)lfs, (void*)dir, path); + LFS_ASSERT(!lfs_mlist_isopen(lfs->mlist, (struct lfs_mlist*)dir)); + + err = lfs_dir_open_(lfs, dir, path); + + LFS_TRACE("lfs_dir_open -> %d", err); + LFS_UNLOCK(lfs->cfg); + return err; +} + +int lfs_dir_close(lfs_t *lfs, lfs_dir_t *dir) { + int err = LFS_LOCK(lfs->cfg); + if (err) { + return err; + } + LFS_TRACE("lfs_dir_close(%p, %p)", (void*)lfs, (void*)dir); + + err = lfs_dir_close_(lfs, dir); + + LFS_TRACE("lfs_dir_close -> %d", err); + LFS_UNLOCK(lfs->cfg); + return err; +} + +int lfs_dir_read(lfs_t *lfs, lfs_dir_t *dir, struct lfs_info *info) { + int err = LFS_LOCK(lfs->cfg); + if (err) { + return err; + } + LFS_TRACE("lfs_dir_read(%p, %p, %p)", + (void*)lfs, (void*)dir, (void*)info); + + err = lfs_dir_read_(lfs, dir, info); + + LFS_TRACE("lfs_dir_read -> %d", err); + LFS_UNLOCK(lfs->cfg); + return err; +} + +int lfs_dir_seek(lfs_t *lfs, lfs_dir_t *dir, lfs_off_t off) { + int err = LFS_LOCK(lfs->cfg); + if (err) { + return err; + } + LFS_TRACE("lfs_dir_seek(%p, %p, %"PRIu32")", + (void*)lfs, (void*)dir, off); + + err = lfs_dir_seek_(lfs, dir, off); + + LFS_TRACE("lfs_dir_seek -> %d", err); + LFS_UNLOCK(lfs->cfg); + return err; +} + +lfs_soff_t lfs_dir_tell(lfs_t *lfs, lfs_dir_t *dir) { + int err = LFS_LOCK(lfs->cfg); + if (err) { + return err; + } + LFS_TRACE("lfs_dir_tell(%p, %p)", (void*)lfs, (void*)dir); + + lfs_soff_t res = lfs_dir_tell_(lfs, dir); + + LFS_TRACE("lfs_dir_tell -> %"PRId32, res); + LFS_UNLOCK(lfs->cfg); + return res; +} + +int lfs_dir_rewind(lfs_t *lfs, lfs_dir_t *dir) { + int err = LFS_LOCK(lfs->cfg); + if (err) { + return err; + } + LFS_TRACE("lfs_dir_rewind(%p, %p)", (void*)lfs, (void*)dir); + + err = lfs_dir_rewind_(lfs, dir); + + LFS_TRACE("lfs_dir_rewind -> %d", err); + LFS_UNLOCK(lfs->cfg); + return err; +} + +int lfs_fs_stat(lfs_t *lfs, struct lfs_fsinfo *fsinfo) { + int err = LFS_LOCK(lfs->cfg); + if (err) { + return err; + } + LFS_TRACE("lfs_fs_stat(%p, %p)", (void*)lfs, (void*)fsinfo); + + err = lfs_fs_stat_(lfs, fsinfo); + + LFS_TRACE("lfs_fs_stat -> %d", err); + LFS_UNLOCK(lfs->cfg); + return err; +} + +lfs_ssize_t lfs_fs_size(lfs_t *lfs) { + int err = LFS_LOCK(lfs->cfg); + if (err) { + return err; + } + LFS_TRACE("lfs_fs_size(%p)", (void*)lfs); + + lfs_ssize_t res = lfs_fs_size_(lfs); + + LFS_TRACE("lfs_fs_size -> %"PRId32, res); + LFS_UNLOCK(lfs->cfg); + return res; +} + +int lfs_fs_traverse(lfs_t *lfs, int (*cb)(void *, lfs_block_t), void *data) { + int err = LFS_LOCK(lfs->cfg); + if (err) { + return err; + } + LFS_TRACE("lfs_fs_traverse(%p, %p, %p)", + (void*)lfs, (void*)(uintptr_t)cb, data); + + err = lfs_fs_traverse_(lfs, cb, data, true); + + LFS_TRACE("lfs_fs_traverse -> %d", err); + LFS_UNLOCK(lfs->cfg); + return err; +} + +#ifndef LFS_READONLY +int lfs_fs_mkconsistent(lfs_t *lfs) { + int err = LFS_LOCK(lfs->cfg); + if (err) { + return err; + } + LFS_TRACE("lfs_fs_mkconsistent(%p)", (void*)lfs); + + err = lfs_fs_mkconsistent_(lfs); + + LFS_TRACE("lfs_fs_mkconsistent -> %d", err); + LFS_UNLOCK(lfs->cfg); + return err; +} +#endif + +#ifndef LFS_READONLY +int lfs_fs_gc(lfs_t *lfs) { + int err = LFS_LOCK(lfs->cfg); + if (err) { + return err; + } + LFS_TRACE("lfs_fs_gc(%p)", (void*)lfs); + + err = lfs_fs_gc_(lfs); + + LFS_TRACE("lfs_fs_gc -> %d", err); + LFS_UNLOCK(lfs->cfg); + return err; +} +#endif + +#ifndef LFS_READONLY +int lfs_fs_grow(lfs_t *lfs, lfs_size_t block_count) { + int err = LFS_LOCK(lfs->cfg); + if (err) { + return err; + } + LFS_TRACE("lfs_fs_grow(%p, %"PRIu32")", (void*)lfs, block_count); + + err = lfs_fs_grow_(lfs, block_count); + + LFS_TRACE("lfs_fs_grow -> %d", err); + LFS_UNLOCK(lfs->cfg); + return err; +} +#endif + +#ifdef LFS_MIGRATE +int lfs_migrate(lfs_t *lfs, const struct lfs_config *cfg) { + int err = LFS_LOCK(cfg); + if (err) { + return err; + } + LFS_TRACE("lfs_migrate(%p, %p {.context=%p, " + ".read=%p, .prog=%p, .erase=%p, .sync=%p, " + ".read_size=%"PRIu32", .prog_size=%"PRIu32", " + ".block_size=%"PRIu32", .block_count=%"PRIu32", " + ".block_cycles=%"PRIu32", .cache_size=%"PRIu32", " + ".lookahead_size=%"PRIu32", .read_buffer=%p, " + ".prog_buffer=%p, .lookahead_buffer=%p, " + ".name_max=%"PRIu32", .file_max=%"PRIu32", " + ".attr_max=%"PRIu32"})", + (void*)lfs, (void*)cfg, cfg->context, + (void*)(uintptr_t)cfg->read, (void*)(uintptr_t)cfg->prog, + (void*)(uintptr_t)cfg->erase, (void*)(uintptr_t)cfg->sync, + cfg->read_size, cfg->prog_size, cfg->block_size, cfg->block_count, + cfg->block_cycles, cfg->cache_size, cfg->lookahead_size, + cfg->read_buffer, cfg->prog_buffer, cfg->lookahead_buffer, + cfg->name_max, cfg->file_max, cfg->attr_max); + + err = lfs_migrate_(lfs, cfg); + + LFS_TRACE("lfs_migrate -> %d", err); + LFS_UNLOCK(cfg); + return err; +} +#endif + diff --git a/src/lib/littlefs/lfs.h b/src/lib/littlefs/lfs.h new file mode 100644 index 0000000..9914502 --- /dev/null +++ b/src/lib/littlefs/lfs.h @@ -0,0 +1,795 @@ +/* + * The little filesystem + * + * Copyright (c) 2022, The littlefs authors. + * Copyright (c) 2017, Arm Limited. All rights reserved. + * SPDX-License-Identifier: BSD-3-Clause + */ +#ifndef LFS_H +#define LFS_H + +#include "lfs_util.h" + +#ifdef __cplusplus +extern "C" +{ +#endif + + +/// Version info /// + +// Software library version +// Major (top-nibble), incremented on backwards incompatible changes +// Minor (bottom-nibble), incremented on feature additions +#define LFS_VERSION 0x00020009 +#define LFS_VERSION_MAJOR (0xffff & (LFS_VERSION >> 16)) +#define LFS_VERSION_MINOR (0xffff & (LFS_VERSION >> 0)) + +// Version of On-disk data structures +// Major (top-nibble), incremented on backwards incompatible changes +// Minor (bottom-nibble), incremented on feature additions +#define LFS_DISK_VERSION 0x00020001 +#define LFS_DISK_VERSION_MAJOR (0xffff & (LFS_DISK_VERSION >> 16)) +#define LFS_DISK_VERSION_MINOR (0xffff & (LFS_DISK_VERSION >> 0)) + + +/// Definitions /// + +// Type definitions +typedef uint32_t lfs_size_t; +typedef uint32_t lfs_off_t; + +typedef int32_t lfs_ssize_t; +typedef int32_t lfs_soff_t; + +typedef uint32_t lfs_block_t; + +// Maximum name size in bytes, may be redefined to reduce the size of the +// info struct. Limited to <= 1022. Stored in superblock and must be +// respected by other littlefs drivers. +#ifndef LFS_NAME_MAX +#define LFS_NAME_MAX 255 +#endif + +// Maximum size of a file in bytes, may be redefined to limit to support other +// drivers. Limited on disk to <= 2147483647. Stored in superblock and must be +// respected by other littlefs drivers. +#ifndef LFS_FILE_MAX +#define LFS_FILE_MAX 2147483647 +#endif + +// Maximum size of custom attributes in bytes, may be redefined, but there is +// no real benefit to using a smaller LFS_ATTR_MAX. Limited to <= 1022. +#ifndef LFS_ATTR_MAX +#define LFS_ATTR_MAX 1022 +#endif + +// Possible error codes, these are negative to allow +// valid positive return values +enum lfs_error { + LFS_ERR_OK = 0, // No error + LFS_ERR_IO = -5, // Error during device operation + LFS_ERR_CORRUPT = -84, // Corrupted + LFS_ERR_NOENT = -2, // No directory entry + LFS_ERR_EXIST = -17, // Entry already exists + LFS_ERR_NOTDIR = -20, // Entry is not a dir + LFS_ERR_ISDIR = -21, // Entry is a dir + LFS_ERR_NOTEMPTY = -39, // Dir is not empty + LFS_ERR_BADF = -9, // Bad file number + LFS_ERR_FBIG = -27, // File too large + LFS_ERR_INVAL = -22, // Invalid parameter + LFS_ERR_NOSPC = -28, // No space left on device + LFS_ERR_NOMEM = -12, // No more memory available + LFS_ERR_NOATTR = -61, // No data/attr available + LFS_ERR_NAMETOOLONG = -36, // File name too long +}; + +// File types +enum lfs_type { + // file types + LFS_TYPE_REG = 0x001, + LFS_TYPE_DIR = 0x002, + + // internally used types + LFS_TYPE_SPLICE = 0x400, + LFS_TYPE_NAME = 0x000, + LFS_TYPE_STRUCT = 0x200, + LFS_TYPE_USERATTR = 0x300, + LFS_TYPE_FROM = 0x100, + LFS_TYPE_TAIL = 0x600, + LFS_TYPE_GLOBALS = 0x700, + LFS_TYPE_CRC = 0x500, + + // internally used type specializations + LFS_TYPE_CREATE = 0x401, + LFS_TYPE_DELETE = 0x4ff, + LFS_TYPE_SUPERBLOCK = 0x0ff, + LFS_TYPE_DIRSTRUCT = 0x200, + LFS_TYPE_CTZSTRUCT = 0x202, + LFS_TYPE_INLINESTRUCT = 0x201, + LFS_TYPE_SOFTTAIL = 0x600, + LFS_TYPE_HARDTAIL = 0x601, + LFS_TYPE_MOVESTATE = 0x7ff, + LFS_TYPE_CCRC = 0x500, + LFS_TYPE_FCRC = 0x5ff, + + // internal chip sources + LFS_FROM_NOOP = 0x000, + LFS_FROM_MOVE = 0x101, + LFS_FROM_USERATTRS = 0x102, +}; + +// File open flags +enum lfs_open_flags { + // open flags + LFS_O_RDONLY = 1, // Open a file as read only +#ifndef LFS_READONLY + LFS_O_WRONLY = 2, // Open a file as write only + LFS_O_RDWR = 3, // Open a file as read and write + LFS_O_CREAT = 0x0100, // Create a file if it does not exist + LFS_O_EXCL = 0x0200, // Fail if a file already exists + LFS_O_TRUNC = 0x0400, // Truncate the existing file to zero size + LFS_O_APPEND = 0x0800, // Move to end of file on every write +#endif + + // internally used flags +#ifndef LFS_READONLY + LFS_F_DIRTY = 0x010000, // File does not match storage + LFS_F_WRITING = 0x020000, // File has been written since last flush +#endif + LFS_F_READING = 0x040000, // File has been read since last flush +#ifndef LFS_READONLY + LFS_F_ERRED = 0x080000, // An error occurred during write +#endif + LFS_F_INLINE = 0x100000, // Currently inlined in directory entry +}; + +// File seek flags +enum lfs_whence_flags { + LFS_SEEK_SET = 0, // Seek relative to an absolute position + LFS_SEEK_CUR = 1, // Seek relative to the current file position + LFS_SEEK_END = 2, // Seek relative to the end of the file +}; + + +// Configuration provided during initialization of the littlefs +struct lfs_config { + // Opaque user provided context that can be used to pass + // information to the block device operations + void *context; + + // Read a region in a block. Negative error codes are propagated + // to the user. + int (*read)(const struct lfs_config *c, lfs_block_t block, + lfs_off_t off, void *buffer, lfs_size_t size); + + // Program a region in a block. The block must have previously + // been erased. Negative error codes are propagated to the user. + // May return LFS_ERR_CORRUPT if the block should be considered bad. + int (*prog)(const struct lfs_config *c, lfs_block_t block, + lfs_off_t off, const void *buffer, lfs_size_t size); + + // Erase a block. A block must be erased before being programmed. + // The state of an erased block is undefined. Negative error codes + // are propagated to the user. + // May return LFS_ERR_CORRUPT if the block should be considered bad. + int (*erase)(const struct lfs_config *c, lfs_block_t block); + + // Sync the state of the underlying block device. Negative error codes + // are propagated to the user. + int (*sync)(const struct lfs_config *c); + +#ifdef LFS_THREADSAFE + // Lock the underlying block device. Negative error codes + // are propagated to the user. + int (*lock)(const struct lfs_config *c); + + // Unlock the underlying block device. Negative error codes + // are propagated to the user. + int (*unlock)(const struct lfs_config *c); +#endif + + // Minimum size of a block read in bytes. All read operations will be a + // multiple of this value. + lfs_size_t read_size; + + // Minimum size of a block program in bytes. All program operations will be + // a multiple of this value. + lfs_size_t prog_size; + + // Size of an erasable block in bytes. This does not impact ram consumption + // and may be larger than the physical erase size. However, non-inlined + // files take up at minimum one block. Must be a multiple of the read and + // program sizes. + lfs_size_t block_size; + + // Number of erasable blocks on the device. + lfs_size_t block_count; + + // Number of erase cycles before littlefs evicts metadata logs and moves + // the metadata to another block. Suggested values are in the + // range 100-1000, with large values having better performance at the cost + // of less consistent wear distribution. + // + // Set to -1 to disable block-level wear-leveling. + int32_t block_cycles; + + // Size of block caches in bytes. Each cache buffers a portion of a block in + // RAM. The littlefs needs a read cache, a program cache, and one additional + // cache per file. Larger caches can improve performance by storing more + // data and reducing the number of disk accesses. Must be a multiple of the + // read and program sizes, and a factor of the block size. + lfs_size_t cache_size; + + // Size of the lookahead buffer in bytes. A larger lookahead buffer + // increases the number of blocks found during an allocation pass. The + // lookahead buffer is stored as a compact bitmap, so each byte of RAM + // can track 8 blocks. + lfs_size_t lookahead_size; + + // Threshold for metadata compaction during lfs_fs_gc in bytes. Metadata + // pairs that exceed this threshold will be compacted during lfs_fs_gc. + // Defaults to ~88% block_size when zero, though the default may change + // in the future. + // + // Note this only affects lfs_fs_gc. Normal compactions still only occur + // when full. + // + // Set to -1 to disable metadata compaction during lfs_fs_gc. + lfs_size_t compact_thresh; + + // Optional statically allocated read buffer. Must be cache_size. + // By default lfs_malloc is used to allocate this buffer. + void *read_buffer; + + // Optional statically allocated program buffer. Must be cache_size. + // By default lfs_malloc is used to allocate this buffer. + void *prog_buffer; + + // Optional statically allocated lookahead buffer. Must be lookahead_size. + // By default lfs_malloc is used to allocate this buffer. + void *lookahead_buffer; + + // Optional upper limit on length of file names in bytes. No downside for + // larger names except the size of the info struct which is controlled by + // the LFS_NAME_MAX define. Defaults to LFS_NAME_MAX when zero. Stored in + // superblock and must be respected by other littlefs drivers. + lfs_size_t name_max; + + // Optional upper limit on files in bytes. No downside for larger files + // but must be <= LFS_FILE_MAX. Defaults to LFS_FILE_MAX when zero. Stored + // in superblock and must be respected by other littlefs drivers. + lfs_size_t file_max; + + // Optional upper limit on custom attributes in bytes. No downside for + // larger attributes size but must be <= LFS_ATTR_MAX. Defaults to + // LFS_ATTR_MAX when zero. + lfs_size_t attr_max; + + // Optional upper limit on total space given to metadata pairs in bytes. On + // devices with large blocks (e.g. 128kB) setting this to a low size (2-8kB) + // can help bound the metadata compaction time. Must be <= block_size. + // Defaults to block_size when zero. + lfs_size_t metadata_max; + + // Optional upper limit on inlined files in bytes. Inlined files live in + // metadata and decrease storage requirements, but may be limited to + // improve metadata-related performance. Must be <= cache_size, <= + // attr_max, and <= block_size/8. Defaults to the largest possible + // inline_max when zero. + // + // Set to -1 to disable inlined files. + lfs_size_t inline_max; + +#ifdef LFS_MULTIVERSION + // On-disk version to use when writing in the form of 16-bit major version + // + 16-bit minor version. This limiting metadata to what is supported by + // older minor versions. Note that some features will be lost. Defaults to + // to the most recent minor version when zero. + uint32_t disk_version; +#endif +}; + +// File info structure +struct lfs_info { + // Type of the file, either LFS_TYPE_REG or LFS_TYPE_DIR + uint8_t type; + + // Size of the file, only valid for REG files. Limited to 32-bits. + lfs_size_t size; + + // Name of the file stored as a null-terminated string. Limited to + // LFS_NAME_MAX+1, which can be changed by redefining LFS_NAME_MAX to + // reduce RAM. LFS_NAME_MAX is stored in superblock and must be + // respected by other littlefs drivers. + char name[LFS_NAME_MAX+1]; +}; + +// Filesystem info structure +struct lfs_fsinfo { + // On-disk version. + uint32_t disk_version; + + // Size of a logical block in bytes. + lfs_size_t block_size; + + // Number of logical blocks in filesystem. + lfs_size_t block_count; + + // Upper limit on the length of file names in bytes. + lfs_size_t name_max; + + // Upper limit on the size of files in bytes. + lfs_size_t file_max; + + // Upper limit on the size of custom attributes in bytes. + lfs_size_t attr_max; +}; + +// Custom attribute structure, used to describe custom attributes +// committed atomically during file writes. +struct lfs_attr { + // 8-bit type of attribute, provided by user and used to + // identify the attribute + uint8_t type; + + // Pointer to buffer containing the attribute + void *buffer; + + // Size of attribute in bytes, limited to LFS_ATTR_MAX + lfs_size_t size; +}; + +// Optional configuration provided during lfs_file_opencfg +struct lfs_file_config { + // Optional statically allocated file buffer. Must be cache_size. + // By default lfs_malloc is used to allocate this buffer. + void *buffer; + + // Optional list of custom attributes related to the file. If the file + // is opened with read access, these attributes will be read from disk + // during the open call. If the file is opened with write access, the + // attributes will be written to disk every file sync or close. This + // write occurs atomically with update to the file's contents. + // + // Custom attributes are uniquely identified by an 8-bit type and limited + // to LFS_ATTR_MAX bytes. When read, if the stored attribute is smaller + // than the buffer, it will be padded with zeros. If the stored attribute + // is larger, then it will be silently truncated. If the attribute is not + // found, it will be created implicitly. + struct lfs_attr *attrs; + + // Number of custom attributes in the list + lfs_size_t attr_count; +}; + + +/// internal littlefs data structures /// +typedef struct lfs_cache { + lfs_block_t block; + lfs_off_t off; + lfs_size_t size; + uint8_t *buffer; +} lfs_cache_t; + +typedef struct lfs_mdir { + lfs_block_t pair[2]; + uint32_t rev; + lfs_off_t off; + uint32_t etag; + uint16_t count; + bool erased; + bool split; + lfs_block_t tail[2]; +} lfs_mdir_t; + +// littlefs directory type +typedef struct lfs_dir { + struct lfs_dir *next; + uint16_t id; + uint8_t type; + lfs_mdir_t m; + + lfs_off_t pos; + lfs_block_t head[2]; +} lfs_dir_t; + +// littlefs file type +typedef struct lfs_file { + struct lfs_file *next; + uint16_t id; + uint8_t type; + lfs_mdir_t m; + + struct lfs_ctz { + lfs_block_t head; + lfs_size_t size; + } ctz; + + uint32_t flags; + lfs_off_t pos; + lfs_block_t block; + lfs_off_t off; + lfs_cache_t cache; + + const struct lfs_file_config *cfg; +} lfs_file_t; + +typedef struct lfs_superblock { + uint32_t version; + lfs_size_t block_size; + lfs_size_t block_count; + lfs_size_t name_max; + lfs_size_t file_max; + lfs_size_t attr_max; +} lfs_superblock_t; + +typedef struct lfs_gstate { + uint32_t tag; + lfs_block_t pair[2]; +} lfs_gstate_t; + +// The littlefs filesystem type +typedef struct lfs { + lfs_cache_t rcache; + lfs_cache_t pcache; + + lfs_block_t root[2]; + struct lfs_mlist { + struct lfs_mlist *next; + uint16_t id; + uint8_t type; + lfs_mdir_t m; + } *mlist; + uint32_t seed; + + lfs_gstate_t gstate; + lfs_gstate_t gdisk; + lfs_gstate_t gdelta; + + struct lfs_lookahead { + lfs_block_t start; + lfs_block_t size; + lfs_block_t next; + lfs_block_t ckpoint; + uint8_t *buffer; + } lookahead; + + const struct lfs_config *cfg; + lfs_size_t block_count; + lfs_size_t name_max; + lfs_size_t file_max; + lfs_size_t attr_max; + lfs_size_t inline_max; + +#ifdef LFS_MIGRATE + struct lfs1 *lfs1; +#endif +} lfs_t; + + +/// Filesystem functions /// + +#ifndef LFS_READONLY +// Format a block device with the littlefs +// +// Requires a littlefs object and config struct. This clobbers the littlefs +// object, and does not leave the filesystem mounted. The config struct must +// be zeroed for defaults and backwards compatibility. +// +// Returns a negative error code on failure. +int lfs_format(lfs_t *lfs, const struct lfs_config *config); +#endif + +// Mounts a littlefs +// +// Requires a littlefs object and config struct. Multiple filesystems +// may be mounted simultaneously with multiple littlefs objects. Both +// lfs and config must be allocated while mounted. The config struct must +// be zeroed for defaults and backwards compatibility. +// +// Returns a negative error code on failure. +int lfs_mount(lfs_t *lfs, const struct lfs_config *config); + +// Unmounts a littlefs +// +// Does nothing besides releasing any allocated resources. +// Returns a negative error code on failure. +int lfs_unmount(lfs_t *lfs); + +/// General operations /// + +#ifndef LFS_READONLY +// Removes a file or directory +// +// If removing a directory, the directory must be empty. +// Returns a negative error code on failure. +int lfs_remove(lfs_t *lfs, const char *path); +#endif + +#ifndef LFS_READONLY +// Rename or move a file or directory +// +// If the destination exists, it must match the source in type. +// If the destination is a directory, the directory must be empty. +// +// Returns a negative error code on failure. +int lfs_rename(lfs_t *lfs, const char *oldpath, const char *newpath); +#endif + +// Find info about a file or directory +// +// Fills out the info structure, based on the specified file or directory. +// Returns a negative error code on failure. +int lfs_stat(lfs_t *lfs, const char *path, struct lfs_info *info); + +// Get a custom attribute +// +// Custom attributes are uniquely identified by an 8-bit type and limited +// to LFS_ATTR_MAX bytes. When read, if the stored attribute is smaller than +// the buffer, it will be padded with zeros. If the stored attribute is larger, +// then it will be silently truncated. If no attribute is found, the error +// LFS_ERR_NOATTR is returned and the buffer is filled with zeros. +// +// Returns the size of the attribute, or a negative error code on failure. +// Note, the returned size is the size of the attribute on disk, irrespective +// of the size of the buffer. This can be used to dynamically allocate a buffer +// or check for existence. +lfs_ssize_t lfs_getattr(lfs_t *lfs, const char *path, + uint8_t type, void *buffer, lfs_size_t size); + +#ifndef LFS_READONLY +// Set custom attributes +// +// Custom attributes are uniquely identified by an 8-bit type and limited +// to LFS_ATTR_MAX bytes. If an attribute is not found, it will be +// implicitly created. +// +// Returns a negative error code on failure. +int lfs_setattr(lfs_t *lfs, const char *path, + uint8_t type, const void *buffer, lfs_size_t size); +#endif + +#ifndef LFS_READONLY +// Removes a custom attribute +// +// If an attribute is not found, nothing happens. +// +// Returns a negative error code on failure. +int lfs_removeattr(lfs_t *lfs, const char *path, uint8_t type); +#endif + + +/// File operations /// + +#ifndef LFS_NO_MALLOC +// Open a file +// +// The mode that the file is opened in is determined by the flags, which +// are values from the enum lfs_open_flags that are bitwise-ored together. +// +// Returns a negative error code on failure. +int lfs_file_open(lfs_t *lfs, lfs_file_t *file, + const char *path, int flags); + +// if LFS_NO_MALLOC is defined, lfs_file_open() will fail with LFS_ERR_NOMEM +// thus use lfs_file_opencfg() with config.buffer set. +#endif + +// Open a file with extra configuration +// +// The mode that the file is opened in is determined by the flags, which +// are values from the enum lfs_open_flags that are bitwise-ored together. +// +// The config struct provides additional config options per file as described +// above. The config struct must remain allocated while the file is open, and +// the config struct must be zeroed for defaults and backwards compatibility. +// +// Returns a negative error code on failure. +int lfs_file_opencfg(lfs_t *lfs, lfs_file_t *file, + const char *path, int flags, + const struct lfs_file_config *config); + +// Close a file +// +// Any pending writes are written out to storage as though +// sync had been called and releases any allocated resources. +// +// Returns a negative error code on failure. +int lfs_file_close(lfs_t *lfs, lfs_file_t *file); + +// Synchronize a file on storage +// +// Any pending writes are written out to storage. +// Returns a negative error code on failure. +int lfs_file_sync(lfs_t *lfs, lfs_file_t *file); + +// Read data from file +// +// Takes a buffer and size indicating where to store the read data. +// Returns the number of bytes read, or a negative error code on failure. +lfs_ssize_t lfs_file_read(lfs_t *lfs, lfs_file_t *file, + void *buffer, lfs_size_t size); + +#ifndef LFS_READONLY +// Write data to file +// +// Takes a buffer and size indicating the data to write. The file will not +// actually be updated on the storage until either sync or close is called. +// +// Returns the number of bytes written, or a negative error code on failure. +lfs_ssize_t lfs_file_write(lfs_t *lfs, lfs_file_t *file, + const void *buffer, lfs_size_t size); +#endif + +// Change the position of the file +// +// The change in position is determined by the offset and whence flag. +// Returns the new position of the file, or a negative error code on failure. +lfs_soff_t lfs_file_seek(lfs_t *lfs, lfs_file_t *file, + lfs_soff_t off, int whence); + +#ifndef LFS_READONLY +// Truncates the size of the file to the specified size +// +// Returns a negative error code on failure. +int lfs_file_truncate(lfs_t *lfs, lfs_file_t *file, lfs_off_t size); +#endif + +// Return the position of the file +// +// Equivalent to lfs_file_seek(lfs, file, 0, LFS_SEEK_CUR) +// Returns the position of the file, or a negative error code on failure. +lfs_soff_t lfs_file_tell(lfs_t *lfs, lfs_file_t *file); + +// Change the position of the file to the beginning of the file +// +// Equivalent to lfs_file_seek(lfs, file, 0, LFS_SEEK_SET) +// Returns a negative error code on failure. +int lfs_file_rewind(lfs_t *lfs, lfs_file_t *file); + +// Return the size of the file +// +// Similar to lfs_file_seek(lfs, file, 0, LFS_SEEK_END) +// Returns the size of the file, or a negative error code on failure. +lfs_soff_t lfs_file_size(lfs_t *lfs, lfs_file_t *file); + + +/// Directory operations /// + +#ifndef LFS_READONLY +// Create a directory +// +// Returns a negative error code on failure. +int lfs_mkdir(lfs_t *lfs, const char *path); +#endif + +// Open a directory +// +// Once open a directory can be used with read to iterate over files. +// Returns a negative error code on failure. +int lfs_dir_open(lfs_t *lfs, lfs_dir_t *dir, const char *path); + +// Close a directory +// +// Releases any allocated resources. +// Returns a negative error code on failure. +int lfs_dir_close(lfs_t *lfs, lfs_dir_t *dir); + +// Read an entry in the directory +// +// Fills out the info structure, based on the specified file or directory. +// Returns a positive value on success, 0 at the end of directory, +// or a negative error code on failure. +int lfs_dir_read(lfs_t *lfs, lfs_dir_t *dir, struct lfs_info *info); + +// Change the position of the directory +// +// The new off must be a value previous returned from tell and specifies +// an absolute offset in the directory seek. +// +// Returns a negative error code on failure. +int lfs_dir_seek(lfs_t *lfs, lfs_dir_t *dir, lfs_off_t off); + +// Return the position of the directory +// +// The returned offset is only meant to be consumed by seek and may not make +// sense, but does indicate the current position in the directory iteration. +// +// Returns the position of the directory, or a negative error code on failure. +lfs_soff_t lfs_dir_tell(lfs_t *lfs, lfs_dir_t *dir); + +// Change the position of the directory to the beginning of the directory +// +// Returns a negative error code on failure. +int lfs_dir_rewind(lfs_t *lfs, lfs_dir_t *dir); + + +/// Filesystem-level filesystem operations + +// Find on-disk info about the filesystem +// +// Fills out the fsinfo structure based on the filesystem found on-disk. +// Returns a negative error code on failure. +int lfs_fs_stat(lfs_t *lfs, struct lfs_fsinfo *fsinfo); + +// Finds the current size of the filesystem +// +// Note: Result is best effort. If files share COW structures, the returned +// size may be larger than the filesystem actually is. +// +// Returns the number of allocated blocks, or a negative error code on failure. +lfs_ssize_t lfs_fs_size(lfs_t *lfs); + +// Traverse through all blocks in use by the filesystem +// +// The provided callback will be called with each block address that is +// currently in use by the filesystem. This can be used to determine which +// blocks are in use or how much of the storage is available. +// +// Returns a negative error code on failure. +int lfs_fs_traverse(lfs_t *lfs, int (*cb)(void*, lfs_block_t), void *data); + +#ifndef LFS_READONLY +// Attempt to make the filesystem consistent and ready for writing +// +// Calling this function is not required, consistency will be implicitly +// enforced on the first operation that writes to the filesystem, but this +// function allows the work to be performed earlier and without other +// filesystem changes. +// +// Returns a negative error code on failure. +int lfs_fs_mkconsistent(lfs_t *lfs); +#endif + +#ifndef LFS_READONLY +// Attempt any janitorial work +// +// This currently: +// 1. Calls mkconsistent if not already consistent +// 2. Compacts metadata > compact_thresh +// 3. Populates the block allocator +// +// Though additional janitorial work may be added in the future. +// +// Calling this function is not required, but may allow the offloading of +// expensive janitorial work to a less time-critical code path. +// +// Returns a negative error code on failure. Accomplishing nothing is not +// an error. +int lfs_fs_gc(lfs_t *lfs); +#endif + +#ifndef LFS_READONLY +// Grows the filesystem to a new size, updating the superblock with the new +// block count. +// +// Note: This is irreversible. +// +// Returns a negative error code on failure. +int lfs_fs_grow(lfs_t *lfs, lfs_size_t block_count); +#endif + +#ifndef LFS_READONLY +#ifdef LFS_MIGRATE +// Attempts to migrate a previous version of littlefs +// +// Behaves similarly to the lfs_format function. Attempts to mount +// the previous version of littlefs and update the filesystem so it can be +// mounted with the current version of littlefs. +// +// Requires a littlefs object and config struct. This clobbers the littlefs +// object, and does not leave the filesystem mounted. The config struct must +// be zeroed for defaults and backwards compatibility. +// +// Returns a negative error code on failure. +int lfs_migrate(lfs_t *lfs, const struct lfs_config *cfg); +#endif +#endif + + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif diff --git a/src/lib/littlefs/lfs_util.c b/src/lib/littlefs/lfs_util.c new file mode 100644 index 0000000..dac72ab --- /dev/null +++ b/src/lib/littlefs/lfs_util.c @@ -0,0 +1,37 @@ +/* + * lfs util functions + * + * Copyright (c) 2022, The littlefs authors. + * Copyright (c) 2017, Arm Limited. All rights reserved. + * SPDX-License-Identifier: BSD-3-Clause + */ +#include "lfs_util.h" + +// Only compile if user does not provide custom config +#ifndef LFS_CONFIG + + +// If user provides their own CRC impl we don't need this +#ifndef LFS_CRC +// Software CRC implementation with small lookup table +uint32_t lfs_crc(uint32_t crc, const void *buffer, size_t size) { + static const uint32_t rtable[16] = { + 0x00000000, 0x1db71064, 0x3b6e20c8, 0x26d930ac, + 0x76dc4190, 0x6b6b51f4, 0x4db26158, 0x5005713c, + 0xedb88320, 0xf00f9344, 0xd6d6a3e8, 0xcb61b38c, + 0x9b64c2b0, 0x86d3d2d4, 0xa00ae278, 0xbdbdf21c, + }; + + const uint8_t *data = buffer; + + for (size_t i = 0; i < size; i++) { + crc = (crc >> 4) ^ rtable[(crc ^ (data[i] >> 0)) & 0xf]; + crc = (crc >> 4) ^ rtable[(crc ^ (data[i] >> 4)) & 0xf]; + } + + return crc; +} +#endif + + +#endif diff --git a/src/lib/littlefs/lfs_util.h b/src/lib/littlefs/lfs_util.h new file mode 100644 index 0000000..4e57700 --- /dev/null +++ b/src/lib/littlefs/lfs_util.h @@ -0,0 +1,255 @@ +/* + * lfs utility functions + * + * Copyright (c) 2022, The littlefs authors. + * Copyright (c) 2017, Arm Limited. All rights reserved. + * SPDX-License-Identifier: BSD-3-Clause + */ +#ifndef LFS_UTIL_H +#define LFS_UTIL_H + +// Users can override lfs_util.h with their own configuration by defining +// LFS_CONFIG as a header file to include (-DLFS_CONFIG=lfs_config.h). +// +// If LFS_CONFIG is used, none of the default utils will be emitted and must be +// provided by the config file. To start, I would suggest copying lfs_util.h +// and modifying as needed. +#ifdef LFS_CONFIG +#define LFS_STRINGIZE(x) LFS_STRINGIZE2(x) +#define LFS_STRINGIZE2(x) #x +#include LFS_STRINGIZE(LFS_CONFIG) +#else + +// System includes +#include +#include +#include +#include + +#ifndef LFS_NO_MALLOC +#include +#endif +#ifndef LFS_NO_ASSERT +#include +#endif +#if !defined(LFS_NO_DEBUG) || \ + !defined(LFS_NO_WARN) || \ + !defined(LFS_NO_ERROR) || \ + defined(LFS_YES_TRACE) +#include +#endif + +#ifdef __cplusplus +extern "C" +{ +#endif + + +// Macros, may be replaced by system specific wrappers. Arguments to these +// macros must not have side-effects as the macros can be removed for a smaller +// code footprint + +// Logging functions +#ifndef LFS_TRACE +#ifdef LFS_YES_TRACE +#define LFS_TRACE_(fmt, ...) \ + printf("%s:%d:trace: " fmt "%s\n", __FILE__, __LINE__, __VA_ARGS__) +#define LFS_TRACE(...) LFS_TRACE_(__VA_ARGS__, "") +#else +#define LFS_TRACE(...) +#endif +#endif + +#ifndef LFS_DEBUG +#ifndef LFS_NO_DEBUG +#define LFS_DEBUG_(fmt, ...) \ + printf("%s:%d:debug: " fmt "%s\n", __FILE__, __LINE__, __VA_ARGS__) +#define LFS_DEBUG(...) LFS_DEBUG_(__VA_ARGS__, "") +#else +#define LFS_DEBUG(...) +#endif +#endif + +#ifndef LFS_WARN +#ifndef LFS_NO_WARN +#define LFS_WARN_(fmt, ...) \ + printf("%s:%d:warn: " fmt "%s\n", __FILE__, __LINE__, __VA_ARGS__) +#define LFS_WARN(...) LFS_WARN_(__VA_ARGS__, "") +#else +#define LFS_WARN(...) +#endif +#endif + +#ifndef LFS_ERROR +#ifndef LFS_NO_ERROR +#define LFS_ERROR_(fmt, ...) \ + printf("%s:%d:error: " fmt "%s\n", __FILE__, __LINE__, __VA_ARGS__) +#define LFS_ERROR(...) LFS_ERROR_(__VA_ARGS__, "") +#else +#define LFS_ERROR(...) +#endif +#endif + +// Runtime assertions +#ifndef LFS_ASSERT +#ifndef LFS_NO_ASSERT +#define LFS_ASSERT(test) assert(test) +#else +#define LFS_ASSERT(test) +#endif +#endif + + +// Builtin functions, these may be replaced by more efficient +// toolchain-specific implementations. LFS_NO_INTRINSICS falls back to a more +// expensive basic C implementation for debugging purposes + +// Min/max functions for unsigned 32-bit numbers +static inline uint32_t lfs_max(uint32_t a, uint32_t b) { + return (a > b) ? a : b; +} + +static inline uint32_t lfs_min(uint32_t a, uint32_t b) { + return (a < b) ? a : b; +} + +// Align to nearest multiple of a size +static inline uint32_t lfs_aligndown(uint32_t a, uint32_t alignment) { + return a - (a % alignment); +} + +static inline uint32_t lfs_alignup(uint32_t a, uint32_t alignment) { + return lfs_aligndown(a + alignment-1, alignment); +} + +// Find the smallest power of 2 greater than or equal to a +static inline uint32_t lfs_npw2(uint32_t a) { +#if !defined(LFS_NO_INTRINSICS) && (defined(__GNUC__) || defined(__CC_ARM)) + return 32 - __builtin_clz(a-1); +#else + uint32_t r = 0; + uint32_t s; + a -= 1; + s = (a > 0xffff) << 4; a >>= s; r |= s; + s = (a > 0xff ) << 3; a >>= s; r |= s; + s = (a > 0xf ) << 2; a >>= s; r |= s; + s = (a > 0x3 ) << 1; a >>= s; r |= s; + return (r | (a >> 1)) + 1; +#endif +} + +// Count the number of trailing binary zeros in a +// lfs_ctz(0) may be undefined +static inline uint32_t lfs_ctz(uint32_t a) { +#if !defined(LFS_NO_INTRINSICS) && defined(__GNUC__) + return __builtin_ctz(a); +#else + return lfs_npw2((a & -a) + 1) - 1; +#endif +} + +// Count the number of binary ones in a +static inline uint32_t lfs_popc(uint32_t a) { +#if !defined(LFS_NO_INTRINSICS) && (defined(__GNUC__) || defined(__CC_ARM)) + return __builtin_popcount(a); +#else + a = a - ((a >> 1) & 0x55555555); + a = (a & 0x33333333) + ((a >> 2) & 0x33333333); + return (((a + (a >> 4)) & 0xf0f0f0f) * 0x1010101) >> 24; +#endif +} + +// Find the sequence comparison of a and b, this is the distance +// between a and b ignoring overflow +static inline int lfs_scmp(uint32_t a, uint32_t b) { + return (int)(unsigned)(a - b); +} + +// Convert between 32-bit little-endian and native order +static inline uint32_t lfs_fromle32(uint32_t a) { +#if (defined( BYTE_ORDER ) && defined( ORDER_LITTLE_ENDIAN ) && BYTE_ORDER == ORDER_LITTLE_ENDIAN ) || \ + (defined(__BYTE_ORDER ) && defined(__ORDER_LITTLE_ENDIAN ) && __BYTE_ORDER == __ORDER_LITTLE_ENDIAN ) || \ + (defined(__BYTE_ORDER__) && defined(__ORDER_LITTLE_ENDIAN__) && __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__) + return a; +#elif !defined(LFS_NO_INTRINSICS) && ( \ + (defined( BYTE_ORDER ) && defined( ORDER_BIG_ENDIAN ) && BYTE_ORDER == ORDER_BIG_ENDIAN ) || \ + (defined(__BYTE_ORDER ) && defined(__ORDER_BIG_ENDIAN ) && __BYTE_ORDER == __ORDER_BIG_ENDIAN ) || \ + (defined(__BYTE_ORDER__) && defined(__ORDER_BIG_ENDIAN__) && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__)) + return __builtin_bswap32(a); +#else + return (((uint8_t*)&a)[0] << 0) | + (((uint8_t*)&a)[1] << 8) | + (((uint8_t*)&a)[2] << 16) | + (((uint8_t*)&a)[3] << 24); +#endif +} + +static inline uint32_t lfs_tole32(uint32_t a) { + return lfs_fromle32(a); +} + +// Convert between 32-bit big-endian and native order +static inline uint32_t lfs_frombe32(uint32_t a) { +#if !defined(LFS_NO_INTRINSICS) && ( \ + (defined( BYTE_ORDER ) && defined( ORDER_LITTLE_ENDIAN ) && BYTE_ORDER == ORDER_LITTLE_ENDIAN ) || \ + (defined(__BYTE_ORDER ) && defined(__ORDER_LITTLE_ENDIAN ) && __BYTE_ORDER == __ORDER_LITTLE_ENDIAN ) || \ + (defined(__BYTE_ORDER__) && defined(__ORDER_LITTLE_ENDIAN__) && __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__)) + return __builtin_bswap32(a); +#elif (defined( BYTE_ORDER ) && defined( ORDER_BIG_ENDIAN ) && BYTE_ORDER == ORDER_BIG_ENDIAN ) || \ + (defined(__BYTE_ORDER ) && defined(__ORDER_BIG_ENDIAN ) && __BYTE_ORDER == __ORDER_BIG_ENDIAN ) || \ + (defined(__BYTE_ORDER__) && defined(__ORDER_BIG_ENDIAN__) && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__) + return a; +#else + return (((uint8_t*)&a)[0] << 24) | + (((uint8_t*)&a)[1] << 16) | + (((uint8_t*)&a)[2] << 8) | + (((uint8_t*)&a)[3] << 0); +#endif +} + +static inline uint32_t lfs_tobe32(uint32_t a) { + return lfs_frombe32(a); +} + +// Calculate CRC-32 with polynomial = 0x04c11db7 +#ifdef LFS_CRC +uint32_t lfs_crc(uint32_t crc, const void *buffer, size_t size) { + return LFS_CRC(crc, buffer, size) +} +#else +uint32_t lfs_crc(uint32_t crc, const void *buffer, size_t size); +#endif + +// Allocate memory, only used if buffers are not provided to littlefs +// +// littlefs current has no alignment requirements, as it only allocates +// byte-level buffers. +static inline void *lfs_malloc(size_t size) { +#if defined(LFS_MALLOC) + return LFS_MALLOC(size); +#elif !defined(LFS_NO_MALLOC) + return malloc(size); +#else + (void)size; + return NULL; +#endif +} + +// Deallocate memory, only used if buffers are not provided to littlefs +static inline void lfs_free(void *p) { +#if defined(LFS_FREE) + LFS_FREE(p); +#elif !defined(LFS_NO_MALLOC) + free(p); +#else + (void)p; +#endif +} + + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif +#endif diff --git a/src/lib/mining_pool/braiins/brains_pool.cpp b/src/lib/mining_pool/braiins/brains_pool.cpp deleted file mode 100644 index 6449b29..0000000 --- a/src/lib/mining_pool/braiins/brains_pool.cpp +++ /dev/null @@ -1,43 +0,0 @@ -#include "brains_pool.hpp" - -void BraiinsPool::prepareRequest(HTTPClient &http) const -{ - http.addHeader("Pool-Auth-Token", poolUser.c_str()); -} - -std::string BraiinsPool::getApiUrl() const -{ - return "https://pool.braiins.com/accounts/profile/json/btc/"; -} - -PoolStats BraiinsPool::parseResponse(const JsonDocument &doc) const -{ - try - { - if (doc["btc"].isNull()) - { - return PoolStats{ - .hashrate = "0", - .dailyEarnings = 0}; - } - - std::string unit = doc["btc"]["hash_rate_unit"].as(); - - static const std::unordered_map multipliers = { - {"Zh/s", 21}, {"Eh/s", 18}, {"Ph/s", 15}, {"Th/s", 12}, {"Gh/s", 9}, {"Mh/s", 6}, {"Kh/s", 3}}; - - int multiplier = multipliers.at(unit); - float hashValue = doc["btc"]["hash_rate_5m"].as(); - - return PoolStats{ - .hashrate = std::to_string(static_cast(std::round(hashValue))) + std::string(multiplier, '0'), - .dailyEarnings = static_cast(doc["btc"]["today_reward"].as() * 100000000)}; - } - catch (const std::exception &e) - { - Serial.printf("Error parsing %s response: %s\n", getPoolName().c_str(), e.what()); - return PoolStats{ - .hashrate = "0", - .dailyEarnings = std::nullopt}; - } -} diff --git a/src/lib/mining_pool/braiins/brains_pool.hpp b/src/lib/mining_pool/braiins/brains_pool.hpp deleted file mode 100644 index d79f66b..0000000 --- a/src/lib/mining_pool/braiins/brains_pool.hpp +++ /dev/null @@ -1,33 +0,0 @@ -#pragma once - -#include "lib/mining_pool/mining_pool_interface.hpp" -#include -#include - -class BraiinsPool : public MiningPoolInterface -{ -public: - void setPoolUser(const std::string &user) override { poolUser = user; } - void prepareRequest(HTTPClient &http) const override; - std::string getApiUrl() const override; - PoolStats parseResponse(const JsonDocument &doc) const override; - bool supportsDailyEarnings() const override { return true; } - bool hasLogo() const override { return true; } - std::string getDisplayLabel() const override { return "BRAIINS/POOL"; } // Fallback if needed - std::string getDailyEarningsLabel() const override { return "sats/earned"; } - std::string getLogoFilename() const override { - return "braiins.bin"; - } - - std::string getPoolName() const override { - return "braiins"; - } - - int getLogoWidth() const override { - return 37; - } - - int getLogoHeight() const override { - return 230; - } -}; \ No newline at end of file diff --git a/src/lib/mining_pool/ckpool/ckpool.cpp b/src/lib/mining_pool/ckpool/ckpool.cpp deleted file mode 100644 index 4c17c7d..0000000 --- a/src/lib/mining_pool/ckpool/ckpool.cpp +++ /dev/null @@ -1,47 +0,0 @@ -#include "ckpool.hpp" - -void CKPool::prepareRequest(HTTPClient &http) const -{ - // Empty as CKPool doesn't need special headers -} - -std::string CKPool::getApiUrl() const -{ - return getBaseUrl() + "/users/" + poolUser; -} - -PoolStats CKPool::parseResponse(const JsonDocument &doc) const -{ - try - { - std::string hashrateStr = doc["hashrate1m"].as(); - - // Special case for "0" - if (hashrateStr == "0") { - return PoolStats{ - .hashrate = "0", - .dailyEarnings = std::nullopt - }; - } - - char unit = hashrateStr.back(); - std::string value = hashrateStr.substr(0, hashrateStr.size() - 1); - - int multiplier = getHashrateMultiplier(unit); - double hashrate = std::stod(value) * std::pow(10, multiplier); - - char buffer[32]; - snprintf(buffer, sizeof(buffer), "%.0f", hashrate); - - return PoolStats{ - .hashrate = buffer, - .dailyEarnings = std::nullopt}; - } - catch (const std::exception &e) - { - Serial.printf("Error parsing %s response: %s\n", getPoolName().c_str(), e.what()); - return PoolStats{ - .hashrate = "0", - .dailyEarnings = std::nullopt}; - } -} \ No newline at end of file diff --git a/src/lib/mining_pool/ckpool/ckpool.hpp b/src/lib/mining_pool/ckpool/ckpool.hpp deleted file mode 100644 index bbf75d1..0000000 --- a/src/lib/mining_pool/ckpool/ckpool.hpp +++ /dev/null @@ -1,25 +0,0 @@ -#pragma once - -#include "lib/mining_pool/mining_pool_interface.hpp" -#include - -class CKPool : public MiningPoolInterface { -public: - void setPoolUser(const std::string& user) override { poolUser = user; } - - void prepareRequest(HTTPClient& http) const override; - std::string getApiUrl() const override; - PoolStats parseResponse(const JsonDocument& doc) const override; - bool supportsDailyEarnings() const override { return false; } - std::string getDailyEarningsLabel() const override { return ""; } - bool hasLogo() const override { return false; } - std::string getDisplayLabel() const override { return "CK/POOL"; } - std::string getPoolName() const override { - return "ckpool"; - } - -protected: - virtual std::string getBaseUrl() const { - return "https://solo.ckpool.org"; - } -}; \ No newline at end of file diff --git a/src/lib/mining_pool/ckpool/eu_ckpool.hpp b/src/lib/mining_pool/ckpool/eu_ckpool.hpp deleted file mode 100644 index 95a9b75..0000000 --- a/src/lib/mining_pool/ckpool/eu_ckpool.hpp +++ /dev/null @@ -1,16 +0,0 @@ -#pragma once - -#include "ckpool.hpp" - -class EUCKPool : public CKPool { -public: - std::string getDisplayLabel() const override { return "CK/POOL"; } - std::string getPoolName() const override { - return "eu_ckpool"; - } - -protected: - std::string getBaseUrl() const override { - return "https://eusolo.ckpool.org"; - } -}; \ No newline at end of file diff --git a/src/lib/mining_pool/gobrrr_pool/gobrrr_pool.cpp b/src/lib/mining_pool/gobrrr_pool/gobrrr_pool.cpp deleted file mode 100644 index 0186fec..0000000 --- a/src/lib/mining_pool/gobrrr_pool/gobrrr_pool.cpp +++ /dev/null @@ -1,6 +0,0 @@ -// src/noderunners/noderunners_pool.cpp -#include "gobrrr_pool.hpp" - -std::string GoBrrrPool::getApiUrl() const { - return "https://pool.gobrrr.me/api/client/" + poolUser; -} \ No newline at end of file diff --git a/src/lib/mining_pool/gobrrr_pool/gobrrr_pool.hpp b/src/lib/mining_pool/gobrrr_pool/gobrrr_pool.hpp deleted file mode 100644 index 8c9ffb8..0000000 --- a/src/lib/mining_pool/gobrrr_pool/gobrrr_pool.hpp +++ /dev/null @@ -1,30 +0,0 @@ - -#pragma once - -#include "lib/mining_pool/mining_pool_interface.hpp" -#include "lib/mining_pool/public_pool/public_pool.hpp" - -#include - -class GoBrrrPool : public PublicPool { -public: - std::string getApiUrl() const override; - bool hasLogo() const override { return true; } - std::string getDisplayLabel() const override { return "GOBRRR/POOL"; } - - std::string getLogoFilename() const override { - return "gobrrr.bin"; - } - - std::string getPoolName() const override { - return "gobrrr_pool"; - } - - int getLogoWidth() const override { - return 122; - } - - int getLogoHeight() const override { - return 122; - } -}; \ No newline at end of file diff --git a/src/lib/mining_pool/logo_data.hpp b/src/lib/mining_pool/logo_data.hpp deleted file mode 100644 index 75dcb35..0000000 --- a/src/lib/mining_pool/logo_data.hpp +++ /dev/null @@ -1,11 +0,0 @@ -#pragma once - -#include -#include - -struct LogoData { - const uint8_t* data; - size_t width; - size_t height; - size_t size; -}; diff --git a/src/lib/mining_pool/mining_pool_interface.cpp b/src/lib/mining_pool/mining_pool_interface.cpp deleted file mode 100644 index ced6cb9..0000000 --- a/src/lib/mining_pool/mining_pool_interface.cpp +++ /dev/null @@ -1,18 +0,0 @@ -#include "mining_pool_interface.hpp" -#include "pool_factory.hpp" - -LogoData MiningPoolInterface::getLogo() const { - if (!hasLogo()) { - return LogoData{nullptr, 0, 0, 0}; - } - - // Check if logo exists - String logoPath = String(PoolFactory::getLogosDir()) + "/" + String(getPoolName().c_str()) + "_logo.bin"; - - if (!LittleFS.exists(logoPath)) { - return LogoData{nullptr, 0, 0, 0}; - } - - // Now load the logo (whether it was just downloaded or already existed) - return PoolFactory::loadLogoFromFS(getPoolName(), this); -} \ No newline at end of file diff --git a/src/lib/mining_pool/mining_pool_interface.hpp b/src/lib/mining_pool/mining_pool_interface.hpp deleted file mode 100644 index 28383a3..0000000 --- a/src/lib/mining_pool/mining_pool_interface.hpp +++ /dev/null @@ -1,35 +0,0 @@ -#pragma once - -#include -#include -#include "pool_stats.hpp" -#include "logo_data.hpp" -#include "lib/shared.hpp" - -class MiningPoolInterface { -public: - virtual ~MiningPoolInterface() = default; - virtual void setPoolUser(const std::string& user) = 0; - virtual void prepareRequest(HTTPClient& http) const = 0; - virtual std::string getApiUrl() const = 0; - virtual PoolStats parseResponse(const JsonDocument& doc) const = 0; - virtual bool hasLogo() const = 0; - virtual LogoData getLogo() const; - virtual std::string getDisplayLabel() const = 0; - virtual bool supportsDailyEarnings() const = 0; - virtual std::string getDailyEarningsLabel() const = 0; - virtual std::string getLogoFilename() const { return ""; } - virtual std::string getPoolName() const = 0; - virtual int getLogoWidth() const { return 0; } - virtual int getLogoHeight() const { return 0; } - std::string getLogoUrl() const { - if (!hasLogo() || getLogoFilename().empty()) { - return ""; - } - std::string baseUrl = preferences.getString("poolLogosUrl", DEFAULT_MINING_POOL_LOGOS_URL).c_str(); - return baseUrl + "/" + getLogoFilename().c_str(); - } - -protected: - std::string poolUser; -}; \ No newline at end of file diff --git a/src/lib/mining_pool/mining_pool_stats_handler.cpp b/src/lib/mining_pool/mining_pool_stats_handler.cpp deleted file mode 100644 index ffd9885..0000000 --- a/src/lib/mining_pool/mining_pool_stats_handler.cpp +++ /dev/null @@ -1,95 +0,0 @@ -#include "mining_pool_stats_handler.hpp" - -std::array parseMiningPoolStatsHashRate(const std::string& hashrate, const MiningPoolInterface& pool) -{ - std::array ret; - ret.fill(""); // Initialize all elements to empty strings - std::string label; - std::string output; - - parseHashrateString(hashrate, label, output, 4); - - std::size_t textLength = output.length(); - // Calculate the position where the digits should start - // Account for the position of the mining pool logo and the hashrate label - std::size_t startIndex = NUM_SCREENS - 1 - textLength; - - // Insert the pickaxe icon just before the digits - if (startIndex > 0) - { - ret[startIndex - 1] = "mdi:pickaxe"; - } - - // Place the digits - for (std::size_t i = 0; i < textLength; ++i) - { - ret[startIndex + i] = output.substr(i, 1); - } - - ret[NUM_SCREENS - 1] = label; - - if (pool.hasLogo()) { - ret[0] = "mdi:miningpool"; - } else { - ret[0] = pool.getDisplayLabel(); - } - - - return ret; -} - - -std::array parseMiningPoolStatsDailyEarnings(int sats, std::string label, const MiningPoolInterface& pool) -{ - std::array ret; - ret.fill(""); // Initialize all elements to empty strings - std::string satsDisplay = std::to_string(sats); - - if (sats >= 100000000) { - // A whale mining 1+ BTC per day! No decimal points; whales scoff at such things. - label = "BTC" + label.substr(4); - satsDisplay = satsDisplay.substr(0, satsDisplay.length() - 8); - } else if (sats >= 10000000) { - // 10.0M to 99.9M you get one decimal point - satsDisplay = satsDisplay.substr(0, satsDisplay.length() - 6) + "." + satsDisplay[2] + "M"; - } else if (sats >= 1000000) { - // 1.00M to 9.99M you get two decimal points - satsDisplay = satsDisplay.substr(0, satsDisplay.length() - 6) + "." + satsDisplay.substr(2, 2) + "M"; - } else if (sats >= 100000) { - // 100K to 999K you get no extra precision - satsDisplay = satsDisplay.substr(0, satsDisplay.length() - 3) + "K"; - } else if (sats >= 10000) { - // 10.0K to 99.9K you get one decimal point - satsDisplay = satsDisplay.substr(0, satsDisplay.length() - 3) + "." + satsDisplay[2] + "K"; - } else { - // Pleb miner! 4 digit or fewer sats will fit as-is. no-op. - } - - std::size_t textLength = satsDisplay.length(); - - // Calculate the position where the digits should start - // Account for the position of the mining pool logo - std::size_t startIndex = NUM_SCREENS - 1 - textLength; - - // Insert the pickaxe icon just before the digits if there's room - if (startIndex > 0) - { - ret[startIndex - 1] = "mdi:pickaxe"; - } - - // Place the digits - for (std::size_t i = 0; i < textLength; ++i) - { - ret[startIndex + i] = satsDisplay.substr(i, 1); - } - - ret[NUM_SCREENS - 1] = label; - - if (pool.hasLogo()) { - ret[0] = "mdi:miningpool"; - } else { - ret[0] = pool.getDisplayLabel(); - } - - return ret; -} \ No newline at end of file diff --git a/src/lib/mining_pool/mining_pool_stats_handler.hpp b/src/lib/mining_pool/mining_pool_stats_handler.hpp deleted file mode 100644 index dcbc1db..0000000 --- a/src/lib/mining_pool/mining_pool_stats_handler.hpp +++ /dev/null @@ -1,11 +0,0 @@ -#include -#include -#include -#include - -#ifndef UNITY_TEST -#include "lib/mining_pool/mining_pool_interface.hpp" -#endif - -std::array parseMiningPoolStatsHashRate(const std::string& hashrate, const MiningPoolInterface& pool); -std::array parseMiningPoolStatsDailyEarnings(int sats, std::string label, const MiningPoolInterface& pool); diff --git a/src/lib/mining_pool/noderunners/noderunners_pool.cpp b/src/lib/mining_pool/noderunners/noderunners_pool.cpp deleted file mode 100644 index e7e10ca..0000000 --- a/src/lib/mining_pool/noderunners/noderunners_pool.cpp +++ /dev/null @@ -1,48 +0,0 @@ -// src/noderunners/noderunners_pool.cpp -#include "noderunners_pool.hpp" - -void NoderunnersPool::prepareRequest(HTTPClient &http) const -{ - // Empty as Noderunners doesn't need special headers -} - -std::string NoderunnersPool::getApiUrl() const -{ - return "https://pool.noderunners.network/api/v1/users/" + poolUser; -} - -PoolStats NoderunnersPool::parseResponse(const JsonDocument &doc) const -{ - try - { - std::string hashrateStr = doc["hashrate1m"].as(); - - // Special case for "0" - if (hashrateStr == "0") { - return PoolStats{ - .hashrate = "0", - .dailyEarnings = std::nullopt - }; - } - - char unit = hashrateStr.back(); - std::string value = hashrateStr.substr(0, hashrateStr.size() - 1); - - int multiplier = getHashrateMultiplier(unit); - double hashrate = std::stod(value) * std::pow(10, multiplier); - - char buffer[32]; - snprintf(buffer, sizeof(buffer), "%.0f", hashrate); - - return PoolStats{ - .hashrate = buffer, - .dailyEarnings = std::nullopt}; - } - catch (const std::exception &e) - { - Serial.printf("Error parsing %s response: %s\n", getPoolName().c_str(), e.what()); - return PoolStats{ - .hashrate = "0", - .dailyEarnings = std::nullopt}; - } -} \ No newline at end of file diff --git a/src/lib/mining_pool/noderunners/noderunners_pool.hpp b/src/lib/mining_pool/noderunners/noderunners_pool.hpp deleted file mode 100644 index 562ff50..0000000 --- a/src/lib/mining_pool/noderunners/noderunners_pool.hpp +++ /dev/null @@ -1,33 +0,0 @@ -#pragma once - -#include "lib/mining_pool/mining_pool_interface.hpp" -#include -#include - -class NoderunnersPool : public MiningPoolInterface { -public: - void setPoolUser(const std::string& user) override { poolUser = user; } - - void prepareRequest(HTTPClient& http) const override; - std::string getApiUrl() const override; - PoolStats parseResponse(const JsonDocument& doc) const override; - bool supportsDailyEarnings() const override { return false; } - std::string getDailyEarningsLabel() const override { return ""; } - bool hasLogo() const override { return true; } - std::string getDisplayLabel() const override { return "NODE/RUNNERS"; } // Fallback if needed - std::string getLogoFilename() const override { - return "noderunners.bin"; - } - - std::string getPoolName() const override { - return "noderunners"; - } - - int getLogoWidth() const override { - return 122; - } - - int getLogoHeight() const override { - return 122; - } -}; \ No newline at end of file diff --git a/src/lib/mining_pool/ocean/ocean_pool.cpp b/src/lib/mining_pool/ocean/ocean_pool.cpp deleted file mode 100644 index cf9bf49..0000000 --- a/src/lib/mining_pool/ocean/ocean_pool.cpp +++ /dev/null @@ -1,29 +0,0 @@ -#include "ocean_pool.hpp" - -void OceanPool::prepareRequest(HTTPClient &http) const -{ - // Empty as Ocean doesn't need special headers -} - -std::string OceanPool::getApiUrl() const -{ - return "https://api.ocean.xyz/v1/statsnap/" + poolUser; -} - -PoolStats OceanPool::parseResponse(const JsonDocument &doc) const -{ - try - { - return PoolStats{ - .hashrate = doc["result"]["hashrate_300s"].as(), - .dailyEarnings = static_cast( - doc["result"]["estimated_earn_next_block"].as() * 100000000)}; - } - catch (const std::exception &e) - { - Serial.printf("Error parsing %s response: %s\n", getPoolName().c_str(), e.what()); - return PoolStats{ - .hashrate = "0", - .dailyEarnings = std::nullopt}; - } -} \ No newline at end of file diff --git a/src/lib/mining_pool/ocean/ocean_pool.hpp b/src/lib/mining_pool/ocean/ocean_pool.hpp deleted file mode 100644 index 3ede176..0000000 --- a/src/lib/mining_pool/ocean/ocean_pool.hpp +++ /dev/null @@ -1,31 +0,0 @@ -#pragma once - -#include "lib/mining_pool/mining_pool_interface.hpp" -#include - -class OceanPool : public MiningPoolInterface { -public: - void setPoolUser(const std::string& user) override { poolUser = user; } - void prepareRequest(HTTPClient& http) const override; - std::string getApiUrl() const override; - PoolStats parseResponse(const JsonDocument& doc) const override; - bool hasLogo() const override { return true; } - std::string getDisplayLabel() const override { return "OCEAN/POOL"; } // Fallback if needed - bool supportsDailyEarnings() const override { return true; } - std::string getDailyEarningsLabel() const override { return "sats/block"; } - std::string getLogoFilename() const override { - return "ocean.bin"; - } - - std::string getPoolName() const override { - return "ocean"; - } - - int getLogoWidth() const override { - return 122; - } - - int getLogoHeight() const override { - return 122; - } -}; \ No newline at end of file diff --git a/src/lib/mining_pool/pool_factory.cpp b/src/lib/mining_pool/pool_factory.cpp deleted file mode 100644 index 45bc6ce..0000000 --- a/src/lib/mining_pool/pool_factory.cpp +++ /dev/null @@ -1,140 +0,0 @@ -#include "pool_factory.hpp" - -const char* PoolFactory::MINING_POOL_NAME_OCEAN = "ocean"; -const char* PoolFactory::MINING_POOL_NAME_NODERUNNERS = "noderunners"; -const char* PoolFactory::MINING_POOL_NAME_BRAIINS = "braiins"; -const char* PoolFactory::MINING_POOL_NAME_SATOSHI_RADIO = "satoshi_radio"; -const char* PoolFactory::MINING_POOL_NAME_PUBLIC_POOL = "public_pool"; -const char* PoolFactory::MINING_POOL_NAME_LOCAL_PUBLIC_POOL = "local_public_pool"; -const char* PoolFactory::MINING_POOL_NAME_GOBRRR_POOL = "gobrrr_pool"; -const char* PoolFactory::MINING_POOL_NAME_CKPOOL = "ckpool"; -const char* PoolFactory::MINING_POOL_NAME_EU_CKPOOL = "eu_ckpool"; -const char* PoolFactory::LOGOS_DIR = "/logos"; - -std::unique_ptr PoolFactory::createPool(const std::string& poolName) { - static const std::unordered_map()>> poolFactories = { - {MINING_POOL_NAME_OCEAN, []() { return std::make_unique(); }}, - {MINING_POOL_NAME_NODERUNNERS, []() { return std::make_unique(); }}, - {MINING_POOL_NAME_BRAIINS, []() { return std::make_unique(); }}, - {MINING_POOL_NAME_SATOSHI_RADIO, []() { return std::make_unique(); }}, - {MINING_POOL_NAME_PUBLIC_POOL, []() { return std::make_unique(); }}, - {MINING_POOL_NAME_LOCAL_PUBLIC_POOL, []() { return std::make_unique(); }}, - {MINING_POOL_NAME_GOBRRR_POOL, []() { return std::make_unique(); }}, - {MINING_POOL_NAME_CKPOOL, []() { return std::make_unique(); }}, - {MINING_POOL_NAME_EU_CKPOOL, []() { return std::make_unique(); }} - }; - - auto it = poolFactories.find(poolName); - if (it == poolFactories.end()) { - return nullptr; - } - return it->second(); -} - -void PoolFactory::downloadPoolLogo(const std::string& poolName, const MiningPoolInterface* poolInterface) -{ - const int MAX_RETRIES = 5; - const int RETRY_DELAY_MS = 1000; // 1 second between retries - - if (!poolInterface || !poolInterface->hasLogo()) { - Serial.println(F("No pool interface or logo")); - return; - } - - // Ensure logos directory exists - if (!LittleFS.exists(LOGOS_DIR)) { - LittleFS.mkdir(LOGOS_DIR); - } - - String logoPath = String(LOGOS_DIR) + "/" + String(poolName.c_str()) + "_logo.bin"; - - // Only download if the logo doesn't exist - if (!LittleFS.exists(logoPath)) { - // Clean up logos directory first - File root = LittleFS.open(LOGOS_DIR, "r"); - if (root) { - File file = root.openNextFile(); - while (file) { - String path = file.path(); - file.close(); - LittleFS.remove(path); - file = root.openNextFile(); - } - root.close(); - } - - // Download new logo with retries - std::string logoUrl = poolInterface->getLogoUrl(); - if (!logoUrl.empty()) { - for (int attempt = 1; attempt <= MAX_RETRIES; attempt++) { - Serial.printf("Downloading pool logo (attempt %d of %d)...\n", attempt, MAX_RETRIES); - - HTTPClient http; - http.setUserAgent(USER_AGENT); - http.begin(logoUrl.c_str()); - int httpCode = http.GET(); - - if (httpCode == 200) { - File file = LittleFS.open(logoPath, "w"); - if (file) { - http.writeToStream(&file); - file.close(); - Serial.println(F("Logo downloaded successfully")); - http.end(); - return; // Success! - } - } - - http.end(); - - if (attempt < MAX_RETRIES) { - Serial.printf("Failed to download logo, HTTP code: %d. Retrying...\n", httpCode); - vTaskDelay(pdMS_TO_TICKS(RETRY_DELAY_MS)); - } else { - Serial.printf("Failed to download logo after %d attempts\n", MAX_RETRIES); - } - } - } - } else { - Serial.println(F("Logo already exists")); - } -} - -LogoData PoolFactory::loadLogoFromFS(const std::string& poolName, const MiningPoolInterface* poolInterface) -{ - // Initialize with dimensions from the pool interface - LogoData logo = {nullptr, - 0, - 0, - 0}; - - String logoPath = String(LOGOS_DIR) + "/" + String(poolName.c_str()) + "_logo.bin"; - if (!LittleFS.exists(logoPath)) { - return logo; - } - - // Only set dimensions if file exists - logo.width = static_cast(poolInterface->getLogoWidth()); - logo.height = static_cast(poolInterface->getLogoHeight()); - - File file = LittleFS.open(logoPath, "r"); - if (!file) { - return logo; - } - - size_t size = file.size(); - uint8_t* buffer = new uint8_t[size]; - - - if (file.read(buffer, size) == size) { - logo.data = buffer; - logo.size = size; - } else { - delete[] buffer; - logo.data = nullptr; - logo.size = 0; - } - - file.close(); - return logo; -} \ No newline at end of file diff --git a/src/lib/mining_pool/pool_factory.hpp b/src/lib/mining_pool/pool_factory.hpp deleted file mode 100644 index 9885d74..0000000 --- a/src/lib/mining_pool/pool_factory.hpp +++ /dev/null @@ -1,65 +0,0 @@ -#pragma once -#include "mining_pool_interface.hpp" -#include -#include -#include "lib/shared.hpp" -#include "lib/config.hpp" - -#include "noderunners/noderunners_pool.hpp" -#include "braiins/brains_pool.hpp" -#include "ocean/ocean_pool.hpp" -#include "satoshi_radio/satoshi_radio_pool.hpp" -#include "public_pool/public_pool.hpp" -#include "public_pool/local_public_pool.hpp" -#include "gobrrr_pool/gobrrr_pool.hpp" -#include "ckpool/ckpool.hpp" -#include "ckpool/eu_ckpool.hpp" -#include -#include - - -class PoolFactory { - public: - static const char* getLogosDir() { return LOGOS_DIR; } - static std::unique_ptr createPool(const std::string& poolName); - static std::vector getAvailablePools() { - return { - MINING_POOL_NAME_OCEAN, - MINING_POOL_NAME_NODERUNNERS, - MINING_POOL_NAME_SATOSHI_RADIO, - MINING_POOL_NAME_BRAIINS, - MINING_POOL_NAME_PUBLIC_POOL, - MINING_POOL_NAME_LOCAL_PUBLIC_POOL, - MINING_POOL_NAME_GOBRRR_POOL, - MINING_POOL_NAME_CKPOOL, - MINING_POOL_NAME_EU_CKPOOL - }; - } - - static std::string getAvailablePoolsAsString() { - const auto pools = getAvailablePools(); - std::string result; - for (size_t i = 0; i < pools.size(); ++i) { - result += pools[i]; - if (i < pools.size() - 1) { - result += ", "; - } - } - return result; - } - - static void downloadPoolLogo(const std::string& poolName, const MiningPoolInterface* poolInterface); - static LogoData loadLogoFromFS(const std::string& poolName, const MiningPoolInterface* poolInterface); - - private: - static const char* MINING_POOL_NAME_OCEAN; - static const char* MINING_POOL_NAME_NODERUNNERS; - static const char* MINING_POOL_NAME_BRAIINS; - static const char* MINING_POOL_NAME_SATOSHI_RADIO; - static const char* MINING_POOL_NAME_PUBLIC_POOL; - static const char* MINING_POOL_NAME_LOCAL_PUBLIC_POOL; - static const char* MINING_POOL_NAME_GOBRRR_POOL; - static const char* MINING_POOL_NAME_CKPOOL; - static const char* MINING_POOL_NAME_EU_CKPOOL; - static const char* LOGOS_DIR; -}; \ No newline at end of file diff --git a/src/lib/mining_pool/pool_stats.hpp b/src/lib/mining_pool/pool_stats.hpp deleted file mode 100644 index 842310a..0000000 --- a/src/lib/mining_pool/pool_stats.hpp +++ /dev/null @@ -1,10 +0,0 @@ - -#pragma once - -#include -#include - -struct PoolStats { - std::string hashrate; - std::optional dailyEarnings; -}; diff --git a/src/lib/mining_pool/public_pool/local_public_pool.cpp b/src/lib/mining_pool/public_pool/local_public_pool.cpp deleted file mode 100644 index 048197c..0000000 --- a/src/lib/mining_pool/public_pool/local_public_pool.cpp +++ /dev/null @@ -1,11 +0,0 @@ -#include "local_public_pool.hpp" -#include "lib/shared.hpp" -#include "lib/defaults.hpp" - -std::string LocalPublicPool::getEndpoint() const { - return preferences.getString("localPoolEndpoint", DEFAULT_LOCAL_POOL_ENDPOINT).c_str(); -} - -std::string LocalPublicPool::getApiUrl() const { - return "http://" + getEndpoint() + "/api/client/" + poolUser; -} \ No newline at end of file diff --git a/src/lib/mining_pool/public_pool/local_public_pool.hpp b/src/lib/mining_pool/public_pool/local_public_pool.hpp deleted file mode 100644 index a9e37ad..0000000 --- a/src/lib/mining_pool/public_pool/local_public_pool.hpp +++ /dev/null @@ -1,11 +0,0 @@ -#pragma once - -#include "public_pool.hpp" - -class LocalPublicPool : public PublicPool { -public: - std::string getApiUrl() const override; - std::string getDisplayLabel() const override { return "LOCAL/POOL"; } -private: - std::string getEndpoint() const; -}; \ No newline at end of file diff --git a/src/lib/mining_pool/public_pool/public_pool.cpp b/src/lib/mining_pool/public_pool/public_pool.cpp deleted file mode 100644 index 8c7c6e2..0000000 --- a/src/lib/mining_pool/public_pool/public_pool.cpp +++ /dev/null @@ -1,32 +0,0 @@ -// src/noderunners/noderunners_pool.cpp -#include "public_pool.hpp" - -std::string PublicPool::getApiUrl() const -{ - return "https://public-pool.io:40557/api/client/" + poolUser; -} - -PoolStats PublicPool::parseResponse(const JsonDocument &doc) const -{ - uint64_t totalHashrate = 0; - - try - { - for (JsonVariantConst worker : doc["workers"].as()) - { - totalHashrate += static_cast(std::llround(worker["hashRate"].as())); - } - } - catch (const std::exception &e) - { - Serial.printf("Error parsing %s response: %s\n", getPoolName().c_str(), e.what()); - return PoolStats{ - .hashrate = "0", - .dailyEarnings = std::nullopt}; - } - - return PoolStats{ - .hashrate = std::to_string(totalHashrate), - .dailyEarnings = std::nullopt // Public Pool doesn't support daily earnings - }; -} \ No newline at end of file diff --git a/src/lib/mining_pool/public_pool/public_pool.hpp b/src/lib/mining_pool/public_pool/public_pool.hpp deleted file mode 100644 index e2fdaed..0000000 --- a/src/lib/mining_pool/public_pool/public_pool.hpp +++ /dev/null @@ -1,15 +0,0 @@ - -#pragma once - -#include "lib/mining_pool/mining_pool_interface.hpp" -#include "lib/mining_pool/noderunners/noderunners_pool.hpp" - -#include - -class PublicPool : public NoderunnersPool { -public: - std::string getApiUrl() const override; - bool hasLogo() const override { return false; } - std::string getDisplayLabel() const override { return "PUBLIC/POOL"; } - PoolStats parseResponse(const JsonDocument& doc) const override; -}; \ No newline at end of file diff --git a/src/lib/mining_pool/satoshi_radio/satoshi_radio_pool.cpp b/src/lib/mining_pool/satoshi_radio/satoshi_radio_pool.cpp deleted file mode 100644 index 39fa107..0000000 --- a/src/lib/mining_pool/satoshi_radio/satoshi_radio_pool.cpp +++ /dev/null @@ -1,7 +0,0 @@ -// src/noderunners/noderunners_pool.cpp -#include "satoshi_radio_pool.hpp" - -std::string SatoshiRadioPool::getApiUrl() const -{ - return "https://pool.satoshiradio.nl/api/v1/users/" + poolUser; -} diff --git a/src/lib/mining_pool/satoshi_radio/satoshi_radio_pool.hpp b/src/lib/mining_pool/satoshi_radio/satoshi_radio_pool.hpp deleted file mode 100644 index d809fb1..0000000 --- a/src/lib/mining_pool/satoshi_radio/satoshi_radio_pool.hpp +++ /dev/null @@ -1,14 +0,0 @@ - -#pragma once - -#include "lib/mining_pool/mining_pool_interface.hpp" -#include "lib/mining_pool/noderunners/noderunners_pool.hpp" - -#include - -class SatoshiRadioPool : public NoderunnersPool { -public: - std::string getApiUrl() const override; - bool hasLogo() const override { return false; } - std::string getDisplayLabel() const override { return "SATOSHI/RADIO"; } // Fallback if needed -}; \ No newline at end of file diff --git a/src/lib/mining_pool_stats_fetch.cpp b/src/lib/mining_pool_stats_fetch.cpp deleted file mode 100644 index e04f208..0000000 --- a/src/lib/mining_pool_stats_fetch.cpp +++ /dev/null @@ -1,121 +0,0 @@ -#include "mining_pool_stats_fetch.hpp" - -void MiningPoolStatsFetch::taskWrapper(void* pvParameters) { - MiningPoolStatsFetch::getInstance().task(); -} - -void MiningPoolStatsFetch::downloadLogoTaskWrapper(void* pvParameters) { - MiningPoolStatsFetch::getInstance().downloadLogoTask(); -} - -std::string MiningPoolStatsFetch::getHashRate() const { - return hashrate; -} - -int MiningPoolStatsFetch::getDailyEarnings() const { - return dailyEarnings; -} - -MiningPoolInterface* MiningPoolStatsFetch::getPool() { - if (!currentPool) { - std::string poolName = preferences.getString("miningPoolName", DEFAULT_MINING_POOL_NAME).c_str(); - currentPool = PoolFactory::createPool(poolName); - } - return currentPool.get(); -} - -const MiningPoolInterface* MiningPoolStatsFetch::getPool() const { - return currentPool.get(); -} - -LogoData MiningPoolStatsFetch::getLogo() const { - if (const auto* pool = getPool()) { - return pool->getLogo(); - } - return LogoData{}; -} - -void MiningPoolStatsFetch::task() { - std::string poolName = preferences.getString("miningPoolName", DEFAULT_MINING_POOL_NAME).c_str(); - auto* poolInterface = getPool(); - if (!poolInterface) return; - - std::string poolUser = preferences.getString("miningPoolUser", DEFAULT_MINING_POOL_USER).c_str(); - - // Main stats fetching loop - for (;;) { - ulTaskNotifyTake(pdTRUE, portMAX_DELAY); - - HTTPClient http; - http.setUserAgent(USER_AGENT); - - poolInterface->setPoolUser(poolUser); - std::string apiUrl = poolInterface->getApiUrl(); - http.begin(apiUrl.c_str()); - if (debugLogEnabled()) { - Serial.printf("Fetching mining pool stats from %s\r\n", apiUrl.c_str()); - } - poolInterface->prepareRequest(http); - int httpCode = http.GET(); - if (httpCode == 200) { - String payload = http.getString(); - JsonDocument doc; - deserializeJson(doc, payload); - - if (debugLogEnabled()) { - Serial.printf("Mining pool stats response: %s\r\n", payload.c_str()); - } - - PoolStats stats = poolInterface->parseResponse(doc); - hashrate = stats.hashrate; - - if (debugLogEnabled()) { - Serial.printf("Mining pool stats parsed hashrate: %s\r\n", stats.hashrate.c_str()); - } - - dailyEarnings = stats.dailyEarnings ? *stats.dailyEarnings : 0; - - if (workQueue != nullptr && (ScreenHandler::getCurrentScreen() == SCREEN_MINING_POOL_STATS_HASHRATE || - ScreenHandler::getCurrentScreen() == SCREEN_MINING_POOL_STATS_EARNINGS)) { - WorkItem priceUpdate = {TASK_MINING_POOL_STATS_UPDATE, 0}; - xQueueSend(workQueue, &priceUpdate, portMAX_DELAY); - } - } else { - Serial.print(F("Error retrieving mining pool data. HTTP status code: ")); - Serial.println(httpCode); - } - } -} - -void MiningPoolStatsFetch::downloadLogoTask() { - std::string poolName = preferences.getString("miningPoolName", DEFAULT_MINING_POOL_NAME).c_str(); - auto* poolInterface = getPool(); - if (!poolInterface) return; - - PoolFactory::downloadPoolLogo(poolName, poolInterface); - - // If we're on the mining pool stats screen, trigger a display update - if (ScreenHandler::getCurrentScreen() == SCREEN_MINING_POOL_STATS_HASHRATE) { - WorkItem priceUpdate = {TASK_MINING_POOL_STATS_UPDATE, 0}; - xQueueSend(workQueue, &priceUpdate, portMAX_DELAY); - } - - xTaskNotifyGive(taskHandle); - vTaskDelete(NULL); -} - -void MiningPoolStatsFetch::setup() { - xTaskCreate(downloadLogoTaskWrapper, - "logoDownload", - (6 * 1024), - NULL, - tskIDLE_PRIORITY, - NULL); - - xTaskCreate(taskWrapper, - "miningPoolStatsFetch", - (6 * 1024), - NULL, - tskIDLE_PRIORITY, - &taskHandle); -} diff --git a/src/lib/mining_pool_stats_fetch.hpp b/src/lib/mining_pool_stats_fetch.hpp deleted file mode 100644 index 9ea351a..0000000 --- a/src/lib/mining_pool_stats_fetch.hpp +++ /dev/null @@ -1,45 +0,0 @@ -#pragma once - -#include -#include -#include -#include - -#include "lib/config.hpp" -#include "lib/shared.hpp" -#include "lib/mining_pool/mining_pool_interface.hpp" -#include "mining_pool/pool_factory.hpp" - -class MiningPoolStatsFetch { -public: - static MiningPoolStatsFetch& getInstance() { - static MiningPoolStatsFetch instance; - return instance; - } - - void setup(); - std::string getHashRate() const; - int getDailyEarnings() const; - TaskHandle_t getTaskHandle() const { return taskHandle; } - static void taskWrapper(void* pvParameters); - static void downloadLogoTaskWrapper(void* pvParameters); - - // Pool interface methods - MiningPoolInterface* getPool(); - const MiningPoolInterface* getPool() const; - LogoData getLogo() const; - -private: - MiningPoolStatsFetch() = default; - ~MiningPoolStatsFetch() = default; - MiningPoolStatsFetch(const MiningPoolStatsFetch&) = delete; - MiningPoolStatsFetch& operator=(const MiningPoolStatsFetch&) = delete; - - void task(); - void downloadLogoTask(); - - TaskHandle_t taskHandle = nullptr; - std::string hashrate; - int dailyEarnings = 0; - std::unique_ptr currentPool; -}; \ No newline at end of file diff --git a/src/lib/nostr_notify.cpp b/src/lib/nostr_notify.cpp deleted file mode 100644 index 5bab443..0000000 --- a/src/lib/nostr_notify.cpp +++ /dev/null @@ -1,339 +0,0 @@ -#include "nostr_notify.hpp" -#include "led_handler.hpp" - -std::vector pools; -nostr::Transport *transport; -TaskHandle_t nostrTaskHandle = NULL; -boolean nostrIsConnected = false; -boolean nostrIsSubscribed = false; -boolean nostrIsSubscribing = true; - -String subIdZap; - -void screenRestoreAfterZapCallback(TimerHandle_t xTimer) -{ - Serial.println("Restoring screen after zap"); - int screenBeforeZap = (int)(uintptr_t)pvTimerGetTimerID(xTimer); - ScreenHandler::setCurrentScreen(screenBeforeZap); - xTimerDelete(xTimer, 0); -} - -void setupNostrNotify(bool asDatasource, bool zapNotify) -{ - nostr::esp32::ESP32Platform::initNostr(false); - // time_t now; - // time(&now); - // struct tm *utcTimeInfo; - // utcTimeInfo = gmtime(&now); - // time_t utcNow = mktime(utcTimeInfo); - // time_t timestamp60MinutesAgo = utcNow - 3600; - - try - { - transport = nostr::esp32::ESP32Platform::getTransport(); - nostr::NostrPool *pool = new nostr::NostrPool(transport); - String relay = preferences.getString("nostrRelay"); - String pubKey = preferences.getString("nostrPubKey"); - pools.push_back(pool); - - std::vector *relays = pool->getConnectedRelays(); - - if (zapNotify) - { - subscribeZaps(pool, relay, 60); - } - - if (asDatasource) - { - String subId = pool->subscribeMany( - {relay}, - {// First filter - { - {"kinds", {"12203"}}, - {"since", {String(getMinutesAgo(60))}}, - {"authors", {pubKey}}, - }}, - handleNostrEventCallback, - onNostrSubscriptionClosed, - onNostrSubscriptionEose - ); - - Serial.println(F("[ Nostr ] Subscribing to Nostr Data Feed")); - } - - for (nostr::NostrRelay *relay : *relays) - { - Serial.println("[ Nostr ] Registering to connection events of: " + relay->getUrl()); - relay->getConnection()->addConnectionStatusListener([](const nostr::ConnectionStatus &status) - { - static const char* STATUS_STRINGS[] = {"UNKNOWN", "CONNECTED", "DISCONNECTED", "ERROR"}; - int statusIndex = static_cast(status); - - nostrIsConnected = (status == nostr::ConnectionStatus::CONNECTED); - if (!nostrIsConnected) { - nostrIsSubscribed = false; - } - }); - } - - } - catch (const std::exception &e) - { - Serial.println("[ Nostr ] Error: " + String(e.what())); - } -} - -void nostrTask(void *pvParameters) -{ - DataSourceType dataSource = getDataSource(); - if(dataSource == NOSTR_SOURCE) { - auto& blockNotify = BlockNotify::getInstance(); - int blockFetch = blockNotify.fetchLatestBlock(); - blockNotify.processNewBlock(blockFetch); - } - - while (1) - { - for (nostr::NostrPool *pool : pools) - { - // Run internal loop: refresh relays, complete pending connections, send - // pending messages - pool->loop(); - if (!nostrIsSubscribed && !nostrIsSubscribing) { - Serial.println(F("Not subscribed")); - subscribeZaps(pool, preferences.getString("nostrRelay"), 1); - } - } - vTaskDelay(pdMS_TO_TICKS(100)); - } -} - -void setupNostrTask() -{ - xTaskCreate(nostrTask, "nostrTask", 8192, NULL, 10, &nostrTaskHandle); -} - -boolean nostrConnected() -{ - return nostrIsConnected; -} - -void onNostrSubscriptionClosed(const String &subId, const String &reason) -{ - // This is the callback that will be called when the subscription is - // closed - Serial.println("[ Nostr ] Subscription closed: " + reason); -} - -void onNostrSubscriptionEose(const String &subId) -{ - // This is the callback that will be called when the subscription is - // EOSE - Serial.println("[ Nostr ] Subscription EOSE: " + subId); - nostrIsSubscribing = false; - nostrIsSubscribed = true; -} - -void handleNostrEventCallback(const String &subId, nostr::SignedNostrEvent *event) -{ - JsonDocument doc; - JsonArray arr = doc["data"].to(); - event->toSendableEvent(arr); - - // Early return if array is invalid - if (arr.size() < 2 || !arr[1].is()) { - return; - } - - JsonObject obj = arr[1].as(); - JsonArray tags = obj["tags"].as(); - if (!tags) { - return; - } - - // Use direct value access instead of multiple comparisons - String typeValue; - uint medianFee = 0; - uint blockHeight = 0; - - for (JsonArray tag : tags) { - if (tag.size() != 2) continue; - - const char *key = tag[0]; - if (!key) continue; - - // Use switch for better performance on string comparisons - switch (key[0]) { - case 't': // type - if (strcmp(key, "type") == 0) { - const char *value = tag[1]; - if (value) typeValue = value; - } - break; - case 'm': // medianFee - if (strcmp(key, "medianFee") == 0) { - medianFee = tag[1].as(); - } - break; - case 'b': // blockHeight - if (strcmp(key, "block") == 0) { - blockHeight = tag[1].as(); - } - break; - } - } - - // Process the data - if (!typeValue.isEmpty()) { - if (typeValue == "priceUsd") { - processNewPrice(obj["content"].as(), CURRENCY_USD); - if (blockHeight != 0) { - auto& blockNotify = BlockNotify::getInstance(); - blockNotify.processNewBlock(blockHeight); - } - } - else if (typeValue == "blockHeight") { - auto& blockNotify = BlockNotify::getInstance(); - blockNotify.processNewBlock(obj["content"].as()); - } - - if (medianFee != 0) { - auto& blockNotify = BlockNotify::getInstance(); - blockNotify.processNewBlockFee(medianFee); - } - } -} - -time_t getMinutesAgo(int min) { - time_t now; - time(&now); - return now - (min * 60); -} - -void subscribeZaps(nostr::NostrPool *pool, const String &relay, int minutesAgo) { - if (subIdZap) { - pool->closeSubscription(subIdZap); - } - nostrIsSubscribing = true; - - subIdZap = pool->subscribeMany( - {relay}, - { - { - {"kinds", {"9735"}}, - {"limit", {"1"}}, - {"since", {String(getMinutesAgo(minutesAgo))}}, - {"#p", {preferences.getString("nostrZapPubkey", DEFAULT_ZAP_NOTIFY_PUBKEY) }}, - // {"#p", [&]() { - // std::initializer_list pubkeys; - // String pubkeysStr = preferences.getString("nostrZapPubkeys", ""); - // if (pubkeysStr.length() > 0) { - // // Assuming pubkeys are comma-separated - // char* str = strdup(pubkeysStr.c_str()); - // char* token = strtok(str, ","); - // std::vector keys; - // while (token != NULL) { - // keys.push_back(String(token)); - // token = strtok(NULL, ","); - // } - // free(str); - // return std::initializer_list(keys.begin(), keys.end()); - // } - // // Return default if no pubkeys found - // return std::initializer_list{ - // preferences.getString("nostrZapPubkey", DEFAULT_ZAP_NOTIFY_PUBKEY) - // }; - // }()}, - }, - }, - handleNostrZapCallback, - onNostrSubscriptionClosed, - onNostrSubscriptionEose); - Serial.println("[ Nostr ] Subscribing to Zap Notifications since " + String(getMinutesAgo(minutesAgo))); -} - -void handleNostrZapCallback(const String &subId, nostr::SignedNostrEvent *event) { - JsonDocument doc; - JsonArray arr = doc["data"].to(); - event->toSendableEvent(arr); - - // Early return if invalid - if (arr.size() < 2 || !arr[1].is()) { - return; - } - - JsonObject obj = arr[1].as(); - JsonArray tags = obj["tags"].as(); - if (!tags) { - return; - } - - uint64_t zapAmount = 0; - String zapPubkey; - - for (JsonArray tag : tags) { - if (tag.size() != 2) continue; - - const char *key = tag[0]; - const char *value = tag[1]; - if (!key || !value) continue; - - if (key[0] == 'b' && strcmp(key, "bolt11") == 0) { - zapAmount = getAmountInSatoshis(std::string(value)); - } - else if (key[0] == 'p' && strcmp(key, "p") == 0) { - zapPubkey = value; - } - } - - if (zapAmount == 0) return; - - std::array textEpdContent = parseZapNotify(zapAmount, preferences.getBool("useSatsSymbol", DEFAULT_USE_SATS_SYMBOL)); - - if (debugLogEnabled()) - { - Serial.printf("Got a zap of %llu sats for %s\n", zapAmount, zapPubkey.c_str()); - } - - uint64_t timerPeriod = 0; - int screenBeforeZap = ScreenHandler::getCurrentScreen(); - if (isTimerActive()) - { - // store timer periode before making inactive to prevent artifacts - timerPeriod = getTimerSeconds(); - esp_timer_stop(screenRotateTimer); - } - ScreenHandler::setCurrentScreen(SCREEN_CUSTOM); - - EPDManager::getInstance().setContent(textEpdContent); - vTaskDelay(pdMS_TO_TICKS(315 * NUM_SCREENS) + pdMS_TO_TICKS(250)); - if (preferences.getBool("ledFlashOnZap", DEFAULT_LED_FLASH_ON_ZAP)) - { - getLedHandler().queueEffect(LED_EFFECT_NOSTR_ZAP); - } - if (timerPeriod > 0) - { - esp_timer_start_periodic(screenRotateTimer, - timerPeriod * usPerSecond); - } else if (preferences.getBool("scrnRestoreZap", DEFAULT_SCREEN_RESTORE_AFTER_ZAP)) { - TimerHandle_t screenRestoreAfterZapTimer = xTimerCreate("screenRestoreAfterZap", pdMS_TO_TICKS(getTimerSeconds() * msPerSecond), pdFALSE, (void*)(uintptr_t)screenBeforeZap, screenRestoreAfterZapCallback); - Serial.println("Starting screen restore after zap"); - xTimerStart(screenRestoreAfterZapTimer, 0); - } -} - -// void onNostrEvent(const String &subId, const nostr::Event &event) { -// // This is the callback that will be called when a new event is received -// if (event.kind == 9735) { -// // Parse the zap amount from the event -// uint16_t amount = parseZapAmount(event); -// if (amount > 0) { -// std::array zapContent = parseZapNotify(amount, true); -// EPDManager::getInstance().setContent(zapContent); - -// if (preferences.getBool("ledFlashOnUpd", DEFAULT_LED_FLASH_ON_UPD)) { -// getLedHandler().queueEffect(LED_FLASH_BLOCK_NOTIFY); -// } -// } -// } -// } \ No newline at end of file diff --git a/src/lib/nostr_notify.hpp b/src/lib/nostr_notify.hpp deleted file mode 100644 index ebbe2cb..0000000 --- a/src/lib/nostr_notify.hpp +++ /dev/null @@ -1,30 +0,0 @@ -#pragma once - -#include "shared.hpp" - -#include -#include -#include - -#include "esp32/ESP32Platform.h" -#include "NostrEvent.h" -#include "NostrPool.h" - -#include "price_notify.hpp" -#include "block_notify.hpp" -#include "lib/timers.hpp" - -void setupNostrNotify(bool asDatasource, bool zapNotify); - -void nostrTask(void *pvParameters); -void setupNostrTask(); - -boolean nostrConnected(); -void handleNostrEventCallback(const String &subId, nostr::SignedNostrEvent *event); -void handleNostrZapCallback(const String &subId, nostr::SignedNostrEvent *event); - -void onNostrSubscriptionClosed(const String &subId, const String &reason); -void onNostrSubscriptionEose(const String &subId); - -time_t getMinutesAgo(int min); -void subscribeZaps(nostr::NostrPool *pool, const String &relay, int minutesAgo); \ No newline at end of file diff --git a/src/lib/ota.cpp b/src/lib/ota.cpp index 2d94d48..945a4d4 100644 --- a/src/lib/ota.cpp +++ b/src/lib/ota.cpp @@ -1,16 +1,9 @@ #include "ota.hpp" -#include "led_handler.hpp" TaskHandle_t taskOtaHandle = NULL; -bool isOtaUpdating = false; -QueueHandle_t otaQueue; - - -void setupOTA() -{ - if (preferences.getBool("otaEnabled", DEFAULT_OTA_ENABLED)) - { +void setupOTA() { + if (preferences.getBool("otaEnabled", true)) { ArduinoOTA.onStart(onOTAStart); ArduinoOTA.onProgress(onOTAProgress); @@ -22,427 +15,129 @@ void setupOTA() ArduinoOTA.setRebootOnSuccess(false); ArduinoOTA.begin(); // downloadUpdate(); - otaQueue = xQueueCreate(1, sizeof(UpdateMessage)); - xTaskCreate(handleOTATask, "handleOTA", 8192, NULL, 20, + xTaskCreate(handleOTATask, "handleOTA", 4096, NULL, tskIDLE_PRIORITY, &taskOtaHandle); } } -void onOTAProgress(unsigned int progress, unsigned int total) -{ +void onOTAProgress(unsigned int progress, unsigned int total) { uint percentage = progress / (total / 100); - auto& ledHandler = getLedHandler(); - auto& pixels = ledHandler.getPixels(); - pixels.fill(pixels.Color(0, 255, 0)); - if (percentage < 100) - { + if (percentage < 100) { pixels.setPixelColor(0, pixels.Color(0, 0, 0)); } - if (percentage < 75) - { + if (percentage < 75) { pixels.setPixelColor(1, pixels.Color(0, 0, 0)); } - if (percentage < 50) - { + if (percentage < 50) { pixels.setPixelColor(2, pixels.Color(0, 0, 0)); } - if (percentage < 25) - { + if (percentage < 25) { pixels.setPixelColor(3, pixels.Color(0, 0, 0)); } pixels.show(); } -void onOTAStart() -{ - EPDManager::getInstance().forceFullRefresh(); +void onOTAStart() { + forceFullRefresh(); std::array epdContent = {"U", "P", "D", "A", "T", "E", "!"}; - EPDManager::getInstance().setContent(epdContent); + setEpdContent(epdContent); // Stop all timers esp_timer_stop(screenRotateTimer); esp_timer_stop(minuteTimer); - isOtaUpdating = true; + // Stop or suspend all tasks // vTaskSuspend(priceUpdateTaskHandle); // vTaskSuspend(blockUpdateTaskHandle); - vTaskSuspend(taskScreenRotateTaskHandle); vTaskSuspend(workerTaskHandle); - vTaskSuspend(eventSourceTaskHandle); - ButtonHandler::suspendTask(); + vTaskSuspend(taskScreenRotateTaskHandle); - // stopWebServer(); - auto& blockNotify = BlockNotify::getInstance(); - blockNotify.stop(); + vTaskSuspend(ledTaskHandle); + vTaskSuspend(buttonTaskHandle); + + stopWebServer(); + stopBlockNotify(); + stopPriceNotify(); } -void handleOTATask(void *parameter) -{ - UpdateMessage msg; - - for (;;) - { - if (xQueueReceive(otaQueue, &msg, 0) == pdTRUE) - { - if (msg.updateType == UPDATE_ALL) { - isOtaUpdating = true; - getLedHandler().queueEffect(LED_FLASH_UPDATE); - int resultWebUi = downloadUpdateHandler(UPDATE_WEBUI); - getLedHandler().queueEffect(LED_FLASH_UPDATE); - int resultFw = downloadUpdateHandler(UPDATE_FIRMWARE); - - if (resultWebUi == 0 && resultFw == 0) { - ESP.restart(); - } else { - getLedHandler().queueEffect(LED_FLASH_ERROR); - vTaskDelay(pdMS_TO_TICKS(3000)); - ESP.restart(); - } - } - } - - ArduinoOTA.handle(); // Allow OTA updates to occur - vTaskDelay(pdMS_TO_TICKS(2000)); +void handleOTATask(void *parameter) { + for (;;) { + ArduinoOTA.handle(); // Allow OTA updates to occur + vTaskDelay(pdMS_TO_TICKS(2500)); } } -ReleaseInfo getLatestRelease(const String &fileToDownload) -{ - String releaseUrl = preferences.getString("gitReleaseUrl"); +void downloadUpdate() { WiFiClientSecure client; -// client.setCACert(isrg_root_x1cert); - client.setCACertBundle(rootca_crt_bundle_start); - - + client.setInsecure(); HTTPClient http; - http.begin(client, releaseUrl); http.setUserAgent(USER_AGENT); + // Send HTTP request to CoinGecko API + http.useHTTP10(true); + + http.begin(client, + "https://api.github.com/repos/btclock/btclock_v3/releases/latest"); int httpCode = http.GET(); - ReleaseInfo info = {"", ""}; + if (httpCode == 200) { + // WiFiClient * stream = http->getStreamPtr(); - if (httpCode > 0) - { - String payload = http.getString(); + JsonDocument filter; + + JsonObject filter_assets_0 = filter["assets"].add(); + filter_assets_0["name"] = true; + filter_assets_0["browser_download_url"] = true; JsonDocument doc; - deserializeJson(doc, payload); - JsonArray assets = doc["assets"]; + DeserializationError error = deserializeJson( + doc, http.getStream(), DeserializationOption::Filter(filter)); - for (JsonObject asset : assets) - { - String assetName = asset["name"].as(); - if (assetName == fileToDownload) - { - info.fileUrl = asset["browser_download_url"].as(); - } - else if (assetName == fileToDownload + ".sha256") - { - info.checksumUrl = asset["browser_download_url"].as(); - } + if (error) { + Serial.print("deserializeJson() failed: "); + Serial.println(error.c_str()); + return; + } - if (!info.fileUrl.isEmpty() && !info.checksumUrl.isEmpty()) - { + String downloadUrl; + for (JsonObject asset : doc["assets"].as()) { + if (asset["name"].as().compareTo("firmware.bin") == 0) { + downloadUrl = asset["browser_download_url"].as(); break; } } - Serial.printf("Latest release URL: %s\r\n", info.fileUrl.c_str()); - Serial.printf("Checksum URL: %s\r\n", info.checksumUrl.c_str()); - } - http.end(); - return info; -} -int downloadUpdateHandler(char updateType) -{ - WiFiClientSecure client; - client.setCACertBundle(rootca_crt_bundle_start); - HTTPClient http; - http.setFollowRedirects(HTTPC_STRICT_FOLLOW_REDIRECTS); + Serial.printf("Download update from %s", downloadUrl); - ReleaseInfo latestRelease; - - switch (updateType) - { - case UPDATE_FIRMWARE: - { - latestRelease = getLatestRelease(getFirmwareFilename()); - } - break; - case UPDATE_WEBUI: - { - latestRelease = getLatestRelease(getWebUiFilename()); - // updateWebUi(latestRelease.fileUrl, U_SPIFFS); - // return 0; - } - break; - } - - // First, download the expected SHA256 - String expectedSHA256 = downloadSHA256(latestRelease.checksumUrl); - if (expectedSHA256.isEmpty()) - { - Serial.println(F("Failed to get SHA256 checksum. Aborting update.")); - return false; - } - - http.begin(client, latestRelease.fileUrl); - http.setUserAgent(USER_AGENT); - - int httpCode = http.GET(); - if (httpCode == HTTP_CODE_OK) - { - int contentLength = http.getSize(); - if (contentLength > 0) - { - // Allocate memory to store the firmware - uint8_t *firmware = (uint8_t *)malloc(contentLength); - if (!firmware) - { - Serial.println(F("Not enough memory to store firmware")); - return false; - } - - WiFiClient *stream = http.getStreamPtr(); - size_t bytesRead = 0; - while (bytesRead < contentLength) - { - size_t available = stream->available(); - if (available) - { - size_t readBytes = stream->readBytes(firmware + bytesRead, available); - bytesRead += readBytes; - } - yield(); // Allow background tasks to run - } - - if (bytesRead != contentLength) - { - Serial.println(F("Failed to read entire firmware")); - free(firmware); - return false; - } - - // Calculate SHA256 - String calculated_sha256 = calculateSHA256(firmware, contentLength); - - Serial.print(F("Calculated checksum: ")); - Serial.println(calculated_sha256); - Serial.print(F("Expected checksum: ")); - Serial.println(expectedSHA256); - - if (calculated_sha256 != expectedSHA256) - { - Serial.println(F("Checksum mismatch. Aborting update.")); - free(firmware); - return false; - } - - Update.onProgress(onOTAProgress); - - if (Update.begin(contentLength, updateType)) - { - onOTAStart(); - size_t written = Update.write(firmware, contentLength); - - if (written == contentLength) - { - Serial.println("Written : " + String(written) + " successfully"); - free(firmware); - } - else - { - Serial.println("Written only : " + String(written) + "/" + String(contentLength) + ". Retry?"); - free(firmware); - return 503; - } - - if (Update.end()) - { - Serial.println(F("OTA done!")); - if (Update.isFinished()) - { - Serial.println(F("Update successfully completed. Rebooting.")); -// ESP.restart(); - } - else - { - Serial.println(F("Update not finished? Something went wrong!")); - free(firmware); - return 503; - } - } - else - { - Serial.println("Error Occurred. Error #: " + String(Update.getError())); - free(firmware); - return 503; - } - } - else - { - Serial.println(F("Not enough space to begin OTA")); - free(firmware); - return 503; - } - } - else - { - Serial.println(F("Invalid content length")); - return 503; - } - } - else - { - Serial.printf("HTTP error: %d\n", httpCode); - return 503; - } - http.end(); - - return 0; -} - -void updateWebUi(String latestRelease, int command) -{ - WiFiClientSecure client; - client.setCACertBundle(rootca_crt_bundle_start); - HTTPClient http; - http.setFollowRedirects(HTTPC_STRICT_FOLLOW_REDIRECTS); - http.begin(client, latestRelease); - http.setUserAgent(USER_AGENT); - - int httpCode = http.GET(); - if (httpCode == HTTP_CODE_OK) - { - int contentLength = http.getSize(); - if (contentLength > 0) - { - uint8_t *buffer = (uint8_t *)malloc(contentLength); - if (buffer) - { - WiFiClient *stream = http.getStreamPtr(); - size_t written = stream->readBytes(buffer, contentLength); - - if (written == contentLength) - { - String expectedSHA256 = ""; - if (command == U_FLASH) - { - expectedSHA256 = downloadSHA256(getFirmwareFilename()); - Serial.print("Expected checksum: "); - Serial.println(expectedSHA256); - } - - String calculated_sha256 = calculateSHA256(buffer, contentLength); - Serial.print("Checksum is "); - Serial.println(calculated_sha256); - if ((command == U_FLASH && expectedSHA256.equals(calculated_sha256)) || command == U_SPIFFS) - { - Serial.println(F("Checksum verified. Proceeding with update.")); - - Update.onProgress(onOTAProgress); - - if (Update.begin(contentLength, command)) - { - onOTAStart(); - - Update.write(buffer, contentLength); - if (Update.end()) - { - Serial.println(F("Update complete. Rebooting.")); - ESP.restart(); - } - else - { - Serial.println(F("Error in update process.")); - } - } - else - { - Serial.println(F("Not enough space to begin OTA")); - } - } - else - { - Serial.println(F("Checksum mismatch. Aborting update.")); - } - } - else - { - Serial.println(F("Error downloading firmware")); - } - free(buffer); - } - else - { - Serial.println(F("Not enough memory to allocate buffer")); - } - } - else - { - Serial.println(F("Invalid content length")); - } - } - else - { - Serial.print(httpCode); - Serial.println("Error on HTTP request"); + // esp_http_client_config_t config = { + // .url = CONFIG_FIRMWARE_UPGRADE_URL, + // }; + // esp_https_ota_config_t ota_config = { + // .http_config = &config, + // }; + // esp_err_t ret = esp_https_ota(&ota_config); + // if (ret == ESP_OK) + // { + // esp_restart(); + // } } } -void onOTAError(ota_error_t error) -{ - Serial.println(F("\nOTA update error, restarting")); - Wire.end(); - SPI.end(); - isOtaUpdating = false; - delay(1000); - ESP.restart(); -} - -void onOTAComplete() -{ - Serial.println(F("\nOTA update finished")); +void onOTAError(ota_error_t error) { + Serial.println("\nOTA update error, restarting"); Wire.end(); SPI.end(); delay(1000); ESP.restart(); } -bool getIsOTAUpdating() -{ - return isOtaUpdating; +void onOTAComplete() { + Serial.println("\nOTA update finished"); + Wire.end(); + SPI.end(); + delay(1000); + ESP.restart(); } - -String downloadSHA256(const String &sha256Url) -{ - if (sha256Url.isEmpty()) - { - Serial.println(F("Failed to get SHA256 file URL")); - return ""; - } - - WiFiClientSecure client; - client.setCACertBundle(rootca_crt_bundle_start); - HTTPClient http; - http.setFollowRedirects(HTTPC_STRICT_FOLLOW_REDIRECTS); - http.begin(client, sha256Url); - http.setUserAgent(USER_AGENT); - - int httpCode = http.GET(); - if (httpCode == HTTP_CODE_OK) - { - String sha256 = http.getString(); - sha256.trim(); // Remove any whitespace or newline characters - return sha256; - } - else - { - Serial.printf("Failed to download SHA256 file. HTTP error: %d\n", httpCode); - return ""; - } -} \ No newline at end of file diff --git a/src/lib/ota.hpp b/src/lib/ota.hpp index 44704f6..8b2ad75 100644 --- a/src/lib/ota.hpp +++ b/src/lib/ota.hpp @@ -1,38 +1,13 @@ -#pragma once - #include #include #include "lib/config.hpp" #include "lib/shared.hpp" -#include "lib/timers.hpp" - -#ifndef UPDATE_MESSAGE_HPP -#define UPDATE_MESSAGE_HPP -typedef struct { - char updateType; -} UpdateMessage; -#endif - -extern QueueHandle_t otaQueue; - -struct ReleaseInfo { - String fileUrl; - String checksumUrl; -}; void setupOTA(); void onOTAStart(); void handleOTATask(void *parameter); void onOTAProgress(unsigned int progress, unsigned int total); -// void downloadUpdate(); +void downloadUpdate(); void onOTAError(ota_error_t error); void onOTAComplete(); -int downloadUpdateHandler(char updateType); -ReleaseInfo getLatestRelease(const String& fileToDownload); - -bool getIsOTAUpdating(); - -void updateWebUi(String latestRelease, int command); -String downloadSHA256(const String& filename); - diff --git a/src/lib/price_fetch.cpp b/src/lib/price_fetch.cpp new file mode 100644 index 0000000..d5e6e10 --- /dev/null +++ b/src/lib/price_fetch.cpp @@ -0,0 +1,57 @@ +#include "price_fetch.hpp" + +const PROGMEM char *cgApiUrl = + "https://api.coingecko.com/api/v3/simple/" + "price?ids=bitcoin&vs_currencies=usd%2Ceur"; + +TaskHandle_t priceFetchTaskHandle; + +void taskPriceFetch(void *pvParameters) { + WiFiClientSecure *client = new WiFiClientSecure; + client->setInsecure(); + for (;;) { + ulTaskNotifyTake(pdTRUE, portMAX_DELAY); + + HTTPClient *http = new HTTPClient(); + http->setUserAgent(USER_AGENT); + + // Send HTTP request to CoinGecko API + http->begin(*client, cgApiUrl); + + int httpCode = http->GET(); + + // Parse JSON response and extract average price + uint usdPrice, eurPrice; + if (httpCode == 200) { + String payload = http->getString(); + JsonDocument doc; + deserializeJson(doc, payload); + // usdPrice = doc["bitcoin"]["usd"]; + eurPrice = doc["bitcoin"]["eur"].as(); + + setPrice(eurPrice); + if (workQueue != nullptr && (getCurrentScreen() == SCREEN_BTC_TICKER || + getCurrentScreen() == SCREEN_MSCW_TIME || + getCurrentScreen() == SCREEN_MARKET_CAP)) { + WorkItem priceUpdate = {TASK_PRICE_UPDATE, 0}; + xQueueSend(workQueue, &priceUpdate, portMAX_DELAY); + } + + preferences.putUInt("lastPrice", eurPrice); + } else { + Serial.print( + F("Error retrieving BTC/USD price (CoinGecko). HTTP status code: ")); + Serial.println(httpCode); + if (httpCode == -1) { + WiFi.reconnect(); + } + } + } +} + +void setupPriceFetchTask() { + xTaskCreate(taskPriceFetch, "priceFetch", (6 * 1024), NULL, tskIDLE_PRIORITY, + &priceFetchTaskHandle); + + xTaskNotifyGive(priceFetchTaskHandle); +} \ No newline at end of file diff --git a/src/lib/price_fetch.hpp b/src/lib/price_fetch.hpp new file mode 100644 index 0000000..7016dda --- /dev/null +++ b/src/lib/price_fetch.hpp @@ -0,0 +1,10 @@ +#include +#include + +#include "lib/config.hpp" +#include "lib/shared.hpp" + +extern TaskHandle_t priceFetchTaskHandle; + +void setupPriceFetchTask(); +void taskPriceFetch(void *pvParameters); \ No newline at end of file diff --git a/src/lib/price_notify.cpp b/src/lib/price_notify.cpp index c851e85..b6ab9a3 100644 --- a/src/lib/price_notify.cpp +++ b/src/lib/price_notify.cpp @@ -1,184 +1,132 @@ #include "price_notify.hpp" -const char *wsServerPrice = "wss://ws.kraken.com/v2"; +const char *wsServerPrice = "wss://ws.coincap.io/prices?assets=bitcoin"; -WebSocketsClient webSocket; -uint currentPrice = 90000; +// const char* coinCapWsCert = R"(-----BEGIN CERTIFICATE----- +// MIIFMjCCBNmgAwIBAgIQBtgXvFyc28MsvQ1HjCnXJTAKBggqhkjOPQQDAjBKMQsw +// CQYDVQQGEwJVUzEZMBcGA1UEChMQQ2xvdWRmbGFyZSwgSW5jLjEgMB4GA1UEAxMX +// Q2xvdWRmbGFyZSBJbmMgRUNDIENBLTMwHhcNMjMwNTEwMDAwMDAwWhcNMjQwNTA5 +// MjM1OTU5WjB1MQswCQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEWMBQG +// A1UEBxMNU2FuIEZyYW5jaXNjbzEZMBcGA1UEChMQQ2xvdWRmbGFyZSwgSW5jLjEe +// MBwGA1UEAxMVc25pLmNsb3VkZmxhcmVzc2wuY29tMFkwEwYHKoZIzj0CAQYIKoZI +// zj0DAQcDQgAEpvFIXzQKHuqTo+IE6c6sB4p0PMXK1KsseEGf2UN/CNRhG5hO7lr8 +// JtXrPZkawWBysZxOsEoetkPrDHMugCLfXKOCA3QwggNwMB8GA1UdIwQYMBaAFKXO +// N+rrsHUOlGeItEX62SQQh5YfMB0GA1UdDgQWBBShsZDJohaR1a5E0Qj7yblZjKDC +// gDA6BgNVHREEMzAxggwqLmNvaW5jYXAuaW+CCmNvaW5jYXAuaW+CFXNuaS5jbG91 +// ZGZsYXJlc3NsLmNvbTAOBgNVHQ8BAf8EBAMCB4AwHQYDVR0lBBYwFAYIKwYBBQUH +// AwEGCCsGAQUFBwMCMHsGA1UdHwR0MHIwN6A1oDOGMWh0dHA6Ly9jcmwzLmRpZ2lj +// ZXJ0LmNvbS9DbG91ZGZsYXJlSW5jRUNDQ0EtMy5jcmwwN6A1oDOGMWh0dHA6Ly9j +// cmw0LmRpZ2ljZXJ0LmNvbS9DbG91ZGZsYXJlSW5jRUNDQ0EtMy5jcmwwPgYDVR0g +// BDcwNTAzBgZngQwBAgIwKTAnBggrBgEFBQcCARYbaHR0cDovL3d3dy5kaWdpY2Vy +// dC5jb20vQ1BTMHYGCCsGAQUFBwEBBGowaDAkBggrBgEFBQcwAYYYaHR0cDovL29j +// c3AuZGlnaWNlcnQuY29tMEAGCCsGAQUFBzAChjRodHRwOi8vY2FjZXJ0cy5kaWdp +// Y2VydC5jb20vQ2xvdWRmbGFyZUluY0VDQ0NBLTMuY3J0MAwGA1UdEwEB/wQCMAAw +// ggF+BgorBgEEAdZ5AgQCBIIBbgSCAWoBaAB1AO7N0GTV2xrOxVy3nbTNE6Iyh0Z8 +// vOzew1FIWUZxH7WbAAABiAPnoRAAAAQDAEYwRAIgAP2W09OozuhmKeKKMsaVBcae +// o+nPHF1WUWk0i387YYYCIDIM1Wll7/4O3GNx2/Fx9bC6pi69Uya4pLxsCfW3fZMe +// AHYASLDja9qmRzQP5WoC+p0w6xxSActW3SyB2bu/qznYhHMAAAGIA+eg+QAABAMA +// RzBFAiEAuNpSqrbx47gYBgBMz5M6q0CnV/WMJqWQOxYFKrwfwVACIH3nCs4bKToT +// e+MiBrqSDaekixk4kPFEQESO9qHCkWY5AHcA2ra/az+1tiKfm8K7XGvocJFxbLtR +// hIU0vaQ9MEjX+6sAAAGIA+eg1gAABAMASDBGAiEAolCFl2IfbOHUPAOxoi4BLclS +// v9FVXb7LwIvTuCfyrEQCIQDcvehwhV9XGopKGl17F2LYYKI7hvlO3RmpPZQJt1da +// MDAKBggqhkjOPQQDAgNHADBEAiAXRWZ/JVMsfpSFFTHQHUSqRnQ/7cCOWx+9svIy +// mYnFZQIgHMEG0Cm7O4cn5KUzKOsTwwK+2U15s/jPUQi2n2IDTEM= +// -----END CERTIFICATE-----)"; + +// WebsocketsClient client; +esp_websocket_client_handle_t clientPrice = NULL; +uint currentPrice = 30000; unsigned long int lastPriceUpdate; bool priceNotifyInit = false; -std::map currencyMap; -std::map lastUpdateMap; -TaskHandle_t priceNotifyTaskHandle; -void onWebsocketPriceEvent(WStype_t type, uint8_t * payload, size_t length); +void setupPriceNotify() { + // currentPrice = preferences.get("lastPrice", 30000); -void setupPriceNotify() -{ - webSocket.beginSSL("ws.kraken.com", 443, "/v2"); - webSocket.onEvent([](WStype_t type, uint8_t * payload, size_t length) { - onWebsocketPriceEvent(type, payload, length); - }); - webSocket.setReconnectInterval(5000); - webSocket.enableHeartbeat(15000, 3000, 2); + esp_websocket_client_config_t config = {.uri = wsServerPrice, + // .task_stack = (7*1024), + // .cert_pem = coinCapWsCert, + .user_agent = USER_AGENT}; - setupPriceNotifyTask(); + clientPrice = esp_websocket_client_init(&config); + esp_websocket_register_events(clientPrice, WEBSOCKET_EVENT_ANY, + onWebsocketPriceEvent, clientPrice); + esp_websocket_client_start(clientPrice); } -void onWebsocketPriceEvent(WStype_t type, uint8_t * payload, size_t length) { - switch(type) { - case WStype_DISCONNECTED: - Serial.println(F("Price WS Connection Closed")); - break; - case WStype_CONNECTED: - { - Serial.println("Connected to " + String(wsServerPrice)); +void onWebsocketPriceEvent(void *handler_args, esp_event_base_t base, + int32_t event_id, void *event_data) { + esp_websocket_event_data_t *data = (esp_websocket_event_data_t *)event_data; - JsonDocument doc; - doc["method"] = "subscribe"; - JsonObject params = doc["params"].to(); - params["channel"] = "ticker"; - params["symbol"][0] = "BTC/USD"; - - webSocket.sendTXT(doc.as().c_str()); - break; + switch (event_id) { + case WEBSOCKET_EVENT_CONNECTED: + Serial.println(F("Connected to CoinCap.io WebSocket")); + priceNotifyInit = true; + + break; + case WEBSOCKET_EVENT_DATA: + onWebsocketPriceMessage(data); + break; + case WEBSOCKET_EVENT_ERROR: + Serial.println(F("Price WS Connnection error")); + break; + case WEBSOCKET_EVENT_DISCONNECTED: + Serial.println(F("Price WS Connnection Closed")); + break; + } +} + +void onWebsocketPriceMessage(esp_websocket_event_data_t *event_data) { + JsonDocument doc; + + deserializeJson(doc, (char *)event_data->data_ptr); + + if (doc.containsKey("bitcoin")) { + if (currentPrice != doc["bitcoin"].as()) { + uint minSecPriceUpd = preferences.getUInt( + "minSecPriceUpd", DEFAULT_SECONDS_BETWEEN_PRICE_UPDATE); + uint currentTime = esp_timer_get_time() / 1000000; + + if (lastPriceUpdate == 0 || + (currentTime - lastPriceUpdate) > minSecPriceUpd) { + // const unsigned long oldPrice = currentPrice; + currentPrice = doc["bitcoin"].as(); + preferences.putUInt("lastPrice", currentPrice); + lastPriceUpdate = currentTime; + // if (abs((int)(oldPrice-currentPrice)) > round(0.0015*oldPrice)) { + if (workQueue != nullptr && (getCurrentScreen() == SCREEN_BTC_TICKER || + getCurrentScreen() == SCREEN_MSCW_TIME || + getCurrentScreen() == SCREEN_MARKET_CAP)) { + WorkItem priceUpdate = {TASK_PRICE_UPDATE, 0}; + xQueueSend(workQueue, &priceUpdate, portMAX_DELAY); } - case WStype_TEXT: - { - JsonDocument doc; - deserializeJson(doc, (char *)payload); - - if (doc["data"][0].is()) - { - float price = doc["data"][0]["last"].as(); - uint roundedPrice = round(price); - if (currentPrice != roundedPrice) - { - processNewPrice(roundedPrice, CURRENCY_USD); - } - } - break; - } - case WStype_BIN: - break; - case WStype_ERROR: - case WStype_FRAGMENT_TEXT_START: - case WStype_FRAGMENT_BIN_START: - case WStype_FRAGMENT: - case WStype_PING: - case WStype_PONG: - case WStype_FRAGMENT_FIN: - break; - } -} - -void processNewPrice(uint newPrice, char currency) -{ - uint minSecPriceUpd = preferences.getUInt( - "minSecPriceUpd", DEFAULT_SECONDS_BETWEEN_PRICE_UPDATE); - uint currentTime = esp_timer_get_time() / 1000000; - - if (lastUpdateMap.find(currency) == lastUpdateMap.end() || - (currentTime - lastUpdateMap[currency]) > minSecPriceUpd) - { - currencyMap[currency] = newPrice; - - // Store price in preferences if enough time has passed - if (lastUpdateMap[currency] == 0 || (currentTime - lastUpdateMap[currency]) > 120) - { - String prefKey = String("lastPrice_") + getCurrencyCode(currency).c_str(); - preferences.putUInt(prefKey.c_str(), newPrice); - } - - lastUpdateMap[currency] = currentTime; - - if (workQueue != nullptr && (ScreenHandler::getCurrentScreen() == SCREEN_BTC_TICKER || - ScreenHandler::getCurrentScreen() == SCREEN_SATS_PER_CURRENCY || - ScreenHandler::getCurrentScreen() == SCREEN_MARKET_CAP)) - { - WorkItem priceUpdate = {TASK_PRICE_UPDATE, currency}; - xQueueSend(workQueue, &priceUpdate, portMAX_DELAY); + //} + } } } } -void loadStoredPrices() -{ - // Load prices for all supported currencies - std::vector currencies = getAvailableCurrencies(); - - for (const std::string ¤cy : currencies) { - // Get first character as the currency identifier - String prefKey = String("lastPrice_") + currency.c_str(); - uint storedPrice = preferences.getUInt(prefKey.c_str(), 0); - - if (storedPrice > 0) { - currencyMap[getCurrencyChar(currency)] = storedPrice; - // Initialize lastUpdateMap to 0 so next update will store immediately - lastUpdateMap[getCurrencyChar(currency)] = 0; - } - } +uint getLastPriceUpdate() { + return lastPriceUpdate; } -uint getLastPriceUpdate(char currency) -{ - if (lastUpdateMap.find(currency) == lastUpdateMap.end()) - { - return 0; - } +uint getPrice() { return currentPrice; } - return lastUpdateMap[currency]; +void setPrice(uint newPrice) { currentPrice = newPrice; } + +bool isPriceNotifyConnected() { + if (clientPrice == NULL) return false; + return esp_websocket_client_is_connected(clientPrice); } -uint getPrice(char currency) -{ - if (currencyMap.find(currency) == currencyMap.end()) - { - return 0; - } - return currencyMap[currency]; -} - -void setPrice(uint newPrice, char currency) -{ - currencyMap[currency] = newPrice; -} - -bool isPriceNotifyConnected() -{ - return webSocket.isConnected(); -} - -bool getPriceNotifyInit() -{ +bool getPriceNotifyInit() { return priceNotifyInit; } -void stopPriceNotify() -{ - webSocket.disconnect(); - if (priceNotifyTaskHandle != NULL) { - vTaskDelete(priceNotifyTaskHandle); - priceNotifyTaskHandle = NULL; - } -} +void stopPriceNotify() { + if (clientPrice == NULL) return; + esp_websocket_client_close(clientPrice, portMAX_DELAY); + esp_websocket_client_stop(clientPrice); + esp_websocket_client_destroy(clientPrice); -void restartPriceNotify() -{ - stopPriceNotify(); - setupPriceNotify(); -} - -void taskPriceNotify(void *pvParameters) -{ - for (;;) - { - webSocket.loop(); - vTaskDelay(10 / portTICK_PERIOD_MS); - } -} - -void setupPriceNotifyTask() -{ - xTaskCreate(taskPriceNotify, "priceNotify", (6 * 1024), NULL, tskIDLE_PRIORITY, - &priceNotifyTaskHandle); + clientPrice = NULL; } \ No newline at end of file diff --git a/src/lib/price_notify.hpp b/src/lib/price_notify.hpp index 6c8c6df..acdd898 100644 --- a/src/lib/price_notify.hpp +++ b/src/lib/price_notify.hpp @@ -2,28 +2,22 @@ #include #include -#include +#include + #include #include "lib/screen_handler.hpp" -extern TaskHandle_t priceNotifyTaskHandle; - void setupPriceNotify(); -void setupPriceNotifyTask(); -void taskPriceNotify(void *pvParameters); -void onWebsocketPriceEvent(WStype_t type, uint8_t * payload, size_t length); +void onWebsocketPriceEvent(void *handler_args, esp_event_base_t base, + int32_t event_id, void *event_data); +void onWebsocketPriceMessage(esp_websocket_event_data_t *event_data); -uint getPrice(char currency); -void setPrice(uint newPrice, char currency); - -void processNewPrice(uint newPrice, char currency); +uint getPrice(); +void setPrice(uint newPrice); bool isPriceNotifyConnected(); void stopPriceNotify(); -void restartPriceNotify(); - bool getPriceNotifyInit(); -uint getLastPriceUpdate(char currency); -void loadStoredPrices(); \ No newline at end of file +uint getLastPriceUpdate(); \ No newline at end of file diff --git a/src/lib/screen_handler.cpp b/src/lib/screen_handler.cpp index 75e59aa..d1215f6 100644 --- a/src/lib/screen_handler.cpp +++ b/src/lib/screen_handler.cpp @@ -1,342 +1,301 @@ #include "screen_handler.hpp" +// TaskHandle_t priceUpdateTaskHandle; +// TaskHandle_t blockUpdateTaskHandle; +// TaskHandle_t timeUpdateTaskHandle; TaskHandle_t taskScreenRotateTaskHandle; TaskHandle_t workerTaskHandle; +esp_timer_handle_t screenRotateTimer; +esp_timer_handle_t minuteTimer; + +std::array taskEpdContent = {"", "", "", "", + "", "", ""}; +std::string priceString; + +#define WORK_QUEUE_SIZE 10 QueueHandle_t workQueue = NULL; -// Initialize static members -uint ScreenHandler::currentScreen = SCREEN_BLOCK_HEIGHT; -uint ScreenHandler::currentCurrency = CURRENCY_USD; +uint currentScreen; -std::array taskEpdContent = {}; - -// Convert existing functions to static member functions -void ScreenHandler::setCurrentScreen(uint newScreen) { - if (newScreen != SCREEN_CUSTOM) { - preferences.putUInt("currentScreen", newScreen); - } - currentScreen = newScreen; - - switch (currentScreen) { - case SCREEN_TIME: { - WorkItem timeUpdate = {TASK_TIME_UPDATE, 0}; - xQueueSend(workQueue, &timeUpdate, portMAX_DELAY); - break; - } - case SCREEN_HALVING_COUNTDOWN: - case SCREEN_BLOCK_HEIGHT: { - WorkItem blockUpdate = {TASK_BLOCK_UPDATE, 0}; - xQueueSend(workQueue, &blockUpdate, portMAX_DELAY); - break; - } - case SCREEN_MARKET_CAP: - case SCREEN_SATS_PER_CURRENCY: - case SCREEN_BTC_TICKER: { - WorkItem priceUpdate = {TASK_PRICE_UPDATE, 0}; - xQueueSend(workQueue, &priceUpdate, portMAX_DELAY); - break; - } - case SCREEN_BLOCK_FEE_RATE: { - WorkItem blockUpdate = {TASK_FEE_UPDATE, 0}; - xQueueSend(workQueue, &blockUpdate, portMAX_DELAY); - break; - } - case SCREEN_BITAXE_BESTDIFF: - case SCREEN_BITAXE_HASHRATE: { - if (preferences.getBool("bitaxeEnabled", DEFAULT_BITAXE_ENABLED)) { - WorkItem bitaxeUpdate = {TASK_BITAXE_UPDATE, 0}; - xQueueSend(workQueue, &bitaxeUpdate, portMAX_DELAY); - } else { - setCurrentScreen(SCREEN_BLOCK_HEIGHT); - return; - } - break; - } - case SCREEN_MINING_POOL_STATS_HASHRATE: - case SCREEN_MINING_POOL_STATS_EARNINGS: { - if (preferences.getBool("miningPoolStats", DEFAULT_MINING_POOL_STATS_ENABLED)) { - WorkItem miningPoolStatsUpdate = {TASK_MINING_POOL_STATS_UPDATE, 0}; - xQueueSend(workQueue, &miningPoolStatsUpdate, portMAX_DELAY); - } else { - setCurrentScreen(SCREEN_BLOCK_HEIGHT); - return; - } - break; - } - } - - if (eventSourceTaskHandle != NULL) xTaskNotifyGive(eventSourceTaskHandle); -} - -void ScreenHandler::setCurrentCurrency(char currency) { - currentCurrency = currency; - preferences.putUChar("lastCurrency", currency); -} - -bool ScreenHandler::isCurrencySpecific(uint screen) { - switch (screen) { - case SCREEN_BTC_TICKER: - case SCREEN_SATS_PER_CURRENCY: - case SCREEN_MARKET_CAP: - return true; - default: - return false; - } -} - -bool ScreenHandler::handleCurrencyRotation(bool forward) { - if ((getDataSource() == BTCLOCK_SOURCE || getDataSource() == CUSTOM_SOURCE) && isCurrencySpecific(getCurrentScreen())) { - std::vector ac = getActiveCurrencies(); - if (ac.empty()) return false; - - std::string curCode = getCurrencyCode(getCurrentCurrency()); - auto it = std::find(ac.begin(), ac.end(), curCode); - - if (it == ac.end()) { - // Current currency not found in active currencies - initialize based on direction - setCurrentCurrency(getCurrencyChar(forward ? ac.front() : ac.back())); - setCurrentScreen(getCurrentScreen()); - return true; - } else if (forward && curCode != ac.back()) { - // Moving forward and not at last currency - setCurrentCurrency(getCurrencyChar(ac.at(std::distance(ac.begin(), it) + 1))); - setCurrentScreen(getCurrentScreen()); - return true; - } else if (!forward && curCode != ac.front()) { - // Moving backward and not at first currency - setCurrentCurrency(getCurrencyChar(ac.at(std::distance(ac.begin(), it) - 1))); - setCurrentScreen(getCurrentScreen()); - return true; - } - // If we're at the last/first currency of current screen, let nextScreen/previousScreen handle it - return false; - } - return false; -} - -int ScreenHandler::findNextVisibleScreen(int currentScreen, bool forward) { - std::vector screenMappings = getScreenNameMap(); - int newScreen; - - if (forward) { - newScreen = (currentScreen < screenMappings.size() - 1) ? - screenMappings[currentScreen + 1].value : screenMappings.front().value; - } else { - newScreen = (currentScreen > 0) ? - screenMappings[currentScreen - 1].value : screenMappings.back().value; - } - - String key = "screen" + String(newScreen) + "Visible"; - while (!preferences.getBool(key.c_str(), true)) { - currentScreen = findScreenIndexByValue(newScreen); - if (forward) { - newScreen = (currentScreen < screenMappings.size() - 1) ? - screenMappings[currentScreen + 1].value : screenMappings.front().value; - } else { - newScreen = (currentScreen > 0) ? - screenMappings[currentScreen - 1].value : screenMappings.back().value; - } - key = "screen" + String(newScreen) + "Visible"; - } - - return newScreen; -} - -void ScreenHandler::nextScreen() { - if (handleCurrencyRotation(true)) return; - - int currentIndex = findScreenIndexByValue(getCurrentScreen()); - int nextScreen = findNextVisibleScreen(currentIndex, true); - - // If moving from a currency-specific screen to another currency-specific screen - // reset to first currency - if (isCurrencySpecific(getCurrentScreen()) && isCurrencySpecific(nextScreen)) { - std::vector ac = getActiveCurrencies(); - if (!ac.empty()) { - setCurrentCurrency(getCurrencyChar(ac.front())); - } - } - - setCurrentScreen(nextScreen); -} - -void ScreenHandler::previousScreen() { - if (handleCurrencyRotation(false)) return; - - int currentIndex = findScreenIndexByValue(getCurrentScreen()); - int prevScreen = findNextVisibleScreen(currentIndex, false); - - // If moving from a currency-specific screen to another currency-specific screen - // reset to last currency - if (isCurrencySpecific(getCurrentScreen()) && isCurrencySpecific(prevScreen)) { - std::vector ac = getActiveCurrencies(); - if (!ac.empty()) { - setCurrentCurrency(getCurrencyChar(ac.back())); - } - } - - setCurrentScreen(prevScreen); -} - -void ScreenHandler::showSystemStatusScreen() { - std::array sysStatusEpdContent; - std::fill(sysStatusEpdContent.begin(), sysStatusEpdContent.end(), ""); - - String ipAddr = WiFi.localIP().toString(); - String subNet = WiFi.subnetMask().toString(); - - sysStatusEpdContent[0] = "IP/Subnet"; - - int ipAddrPos = 0; - int subnetPos = 0; - for (int i = 0; i < 4; i++) { - sysStatusEpdContent[1 + i] = ipAddr.substring(0, ipAddr.indexOf('.')) + - "/" + subNet.substring(0, subNet.indexOf('.')); - ipAddrPos = ipAddr.indexOf('.') + 1; - subnetPos = subNet.indexOf('.') + 1; - ipAddr = ipAddr.substring(ipAddrPos); - subNet = subNet.substring(subnetPos); - } - sysStatusEpdContent[NUM_SCREENS - 2] = "RAM/Status"; - - sysStatusEpdContent[NUM_SCREENS - 1] = - String((int)round(ESP.getFreeHeap() / 1024)) + "/" + - (int)round(ESP.getHeapSize() / 1024); - setCurrentScreen(SCREEN_CUSTOM); - EPDManager::getInstance().setContent(sysStatusEpdContent); -} - -// Keep these as free functions void workerTask(void *pvParameters) { - WorkItem receivedItem; + WorkItem receivedItem; - while (1) { - if (xQueueReceive(workQueue, &receivedItem, portMAX_DELAY)) { - uint currentScreenValue = ScreenHandler::getCurrentScreen(); - - switch (receivedItem.type) { - case TASK_BITAXE_UPDATE: { - if (currentScreenValue != SCREEN_BITAXE_HASHRATE && - currentScreenValue != SCREEN_BITAXE_BESTDIFF) break; - - taskEpdContent = (currentScreenValue == SCREEN_BITAXE_HASHRATE) ? - parseBitaxeHashRate(BitAxeFetch::getInstance().getHashRate()) : - parseBitaxeBestDiff(BitAxeFetch::getInstance().getBestDiff()); - EPDManager::getInstance().setContent(taskEpdContent); - break; - } + while (1) { + // Wait for a work item to be available in the queue + if (xQueueReceive(workQueue, &receivedItem, portMAX_DELAY)) { + uint firstIndex = 0; - case TASK_MINING_POOL_STATS_UPDATE: { - if (currentScreenValue != SCREEN_MINING_POOL_STATS_HASHRATE && - currentScreenValue != SCREEN_MINING_POOL_STATS_EARNINGS) break; - - taskEpdContent = (currentScreenValue == SCREEN_MINING_POOL_STATS_HASHRATE) ? - parseMiningPoolStatsHashRate(MiningPoolStatsFetch::getInstance().getHashRate(), *MiningPoolStatsFetch::getInstance().getPool()) : - parseMiningPoolStatsDailyEarnings(MiningPoolStatsFetch::getInstance().getDailyEarnings(), - MiningPoolStatsFetch::getInstance().getPool()->getDailyEarningsLabel(), - *MiningPoolStatsFetch::getInstance().getPool()); - EPDManager::getInstance().setContent(taskEpdContent); - break; - } + // Process the work item based on its type + switch (receivedItem.type) { + case TASK_PRICE_UPDATE: { + uint price = getPrice(); + char priceSymbol = '$'; + if (preferences.getBool("fetchEurPrice", false)) { + priceSymbol = '['; + } + if (getCurrentScreen() == SCREEN_BTC_TICKER) { + taskEpdContent = parsePriceData(price, priceSymbol, preferences.getBool("suffixPrice", false)); + } else if (getCurrentScreen() == SCREEN_MSCW_TIME) { + taskEpdContent = parseSatsPerCurrency(price, priceSymbol, preferences.getBool("useSatsSymbol", false)); + } else { + taskEpdContent = + parseMarketCap(getBlockHeight(), price, priceSymbol, + preferences.getBool("mcapBigChar", true)); + } - case TASK_PRICE_UPDATE: { - uint currency = ScreenHandler::getCurrentCurrency(); - uint price = getPrice(currency); - - if (currentScreenValue == SCREEN_BTC_TICKER) { - taskEpdContent = parsePriceData(price, currency, preferences.getBool("suffixPrice", DEFAULT_SUFFIX_PRICE), - preferences.getBool("mowMode", DEFAULT_MOW_MODE), - preferences.getBool("suffixShareDot", DEFAULT_SUFFIX_SHARE_DOT) - ); - } else if (currentScreenValue == SCREEN_SATS_PER_CURRENCY) { - taskEpdContent = parseSatsPerCurrency(price, currency, preferences.getBool("useSatsSymbol", DEFAULT_USE_SATS_SYMBOL)); - } else { - auto& blockNotify = BlockNotify::getInstance(); - taskEpdContent = parseMarketCap(blockNotify.getBlockHeight(), price, currency, preferences.getBool("mcapBigChar", DEFAULT_MCAP_BIG_CHAR)); - } - - EPDManager::getInstance().setContent(taskEpdContent); - break; - } - case TASK_FEE_UPDATE: { - if (currentScreenValue == SCREEN_BLOCK_FEE_RATE) { - auto& blockNotify = BlockNotify::getInstance(); - taskEpdContent = parseBlockFees(static_cast(blockNotify.getBlockMedianFee())); - EPDManager::getInstance().setContent(taskEpdContent); - } - break; - } - case TASK_BLOCK_UPDATE: { - if (currentScreenValue != SCREEN_HALVING_COUNTDOWN) { - auto& blockNotify = BlockNotify::getInstance(); - taskEpdContent = parseBlockHeight(blockNotify.getBlockHeight()); - } else { - auto& blockNotify = BlockNotify::getInstance(); - taskEpdContent = parseHalvingCountdown(blockNotify.getBlockHeight(), preferences.getBool("useBlkCountdown", DEFAULT_USE_BLOCK_COUNTDOWN)); - } - - if (currentScreenValue == SCREEN_HALVING_COUNTDOWN || - currentScreenValue == SCREEN_BLOCK_HEIGHT) { - EPDManager::getInstance().setContent(taskEpdContent); - } - break; - } - case TASK_TIME_UPDATE: { - if (currentScreenValue == SCREEN_TIME) { - time_t currentTime; - struct tm timeinfo; - time(¤tTime); - localtime_r(¤tTime, &timeinfo); - std::string timeString; - - String minute = String(timeinfo.tm_min); - if (minute.length() < 2) { - minute = "0" + minute; - } - - timeString = - std::to_string(timeinfo.tm_hour) + ":" + minute.c_str(); - timeString.insert(timeString.begin(), - NUM_SCREENS - timeString.length(), ' '); - taskEpdContent[0] = std::to_string(timeinfo.tm_mday) + "/" + - std::to_string(timeinfo.tm_mon + 1); - - for (uint i = 1; i < NUM_SCREENS; i++) { - taskEpdContent[i] = timeString[i]; - } - EPDManager::getInstance().setContent(taskEpdContent); - } - - break; - } - // Add more cases for additional task types - } + setEpdContent(taskEpdContent); + break; } + case TASK_FEE_UPDATE: { + if (getCurrentScreen() == SCREEN_BLOCK_FEE_RATE) { + taskEpdContent = parseBlockFees(static_cast(getBlockMedianFee())); + setEpdContent(taskEpdContent); + } + break; + } + case TASK_BLOCK_UPDATE: { + if (getCurrentScreen() != SCREEN_HALVING_COUNTDOWN) { + taskEpdContent = parseBlockHeight(getBlockHeight()); + } else { + taskEpdContent = parseHalvingCountdown(getBlockHeight(), preferences.getBool("useBlkCountdown", false)); + } + + if (getCurrentScreen() == SCREEN_HALVING_COUNTDOWN || + getCurrentScreen() == SCREEN_BLOCK_HEIGHT) { + setEpdContent(taskEpdContent); + } + break; + } + case TASK_TIME_UPDATE: { + if (getCurrentScreen() == SCREEN_TIME) { + time_t currentTime; + struct tm timeinfo; + time(¤tTime); + localtime_r(¤tTime, &timeinfo); + std::string timeString; + + String minute = String(timeinfo.tm_min); + if (minute.length() < 2) { + minute = "0" + minute; + } + + timeString = + std::to_string(timeinfo.tm_hour) + ":" + minute.c_str(); + timeString.insert(timeString.begin(), + NUM_SCREENS - timeString.length(), ' '); + taskEpdContent[0] = std::to_string(timeinfo.tm_mday) + "/" + + std::to_string(timeinfo.tm_mon + 1); + + for (uint i = 1; i < NUM_SCREENS; i++) { + taskEpdContent[i] = timeString[i]; + } + setEpdContent(taskEpdContent); + } + + break; + } + // Add more cases for additional task types + } } + } } void taskScreenRotate(void *pvParameters) { - for (;;) { - ulTaskNotifyTake(pdTRUE, portMAX_DELAY); - ScreenHandler::nextScreen(); + for (;;) { + ulTaskNotifyTake(pdTRUE, portMAX_DELAY); + + int nextScreen = (currentScreen + 1) % SCREEN_COUNT; + String key = "screen" + String(nextScreen) + "Visible"; + + while (!preferences.getBool(key.c_str(), true)) { + nextScreen = (nextScreen + 1) % SCREEN_COUNT; + key = "screen" + String(nextScreen) + "Visible"; } + + setCurrentScreen(nextScreen); + } +} + +void IRAM_ATTR minuteTimerISR(void *arg) { + BaseType_t xHigherPriorityTaskWoken = pdFALSE; + // vTaskNotifyGiveFromISR(timeUpdateTaskHandle, &xHigherPriorityTaskWoken); + WorkItem timeUpdate = {TASK_TIME_UPDATE, 0}; + xQueueSendFromISR(workQueue, &timeUpdate, &xHigherPriorityTaskWoken); + if (priceFetchTaskHandle != NULL) { + vTaskNotifyGiveFromISR(priceFetchTaskHandle, &xHigherPriorityTaskWoken); + } + if (xHigherPriorityTaskWoken == pdTRUE) { + portYIELD_FROM_ISR(); + } +} + +void IRAM_ATTR screenRotateTimerISR(void *arg) { + BaseType_t xHigherPriorityTaskWoken = pdFALSE; + vTaskNotifyGiveFromISR(taskScreenRotateTaskHandle, &xHigherPriorityTaskWoken); + if (xHigherPriorityTaskWoken == pdTRUE) { + portYIELD_FROM_ISR(); + } } void setupTasks() { - workQueue = xQueueCreate(WORK_QUEUE_SIZE, sizeof(WorkItem)); - loadStoredPrices(); + workQueue = xQueueCreate(WORK_QUEUE_SIZE, sizeof(WorkItem)); - xTaskCreate(workerTask, "workerTask", 4096, NULL, tskIDLE_PRIORITY, - &workerTaskHandle); + xTaskCreate(workerTask, "workerTask", 4096, NULL, tskIDLE_PRIORITY, + &workerTaskHandle); - xTaskCreate(taskScreenRotate, "rotateScreen", 4096, NULL, tskIDLE_PRIORITY, - &taskScreenRotateTaskHandle); + xTaskCreate(taskScreenRotate, "rotateScreen", 2048, NULL, tskIDLE_PRIORITY, + &taskScreenRotateTaskHandle); - if (findScreenIndexByValue(preferences.getUInt("currentScreen", DEFAULT_CURRENT_SCREEN)) != -1) - ScreenHandler::setCurrentScreen(preferences.getUInt("currentScreen", DEFAULT_CURRENT_SCREEN)); + waitUntilNoneBusy(); + setCurrentScreen(preferences.getUInt("currentScreen", 0)); } -void cleanup() { - vQueueDelete(workQueue); - // Add any other cleanup needed +void setupTimeUpdateTimer(void *pvParameters) { + const esp_timer_create_args_t minuteTimerConfig = { + .callback = &minuteTimerISR, .name = "minute_timer"}; + + esp_timer_create(&minuteTimerConfig, &minuteTimer); + + time_t currentTime; + struct tm timeinfo; + time(¤tTime); + localtime_r(¤tTime, &timeinfo); + uint32_t secondsUntilNextMinute = 60 - timeinfo.tm_sec; + + if (secondsUntilNextMinute > 0) + vTaskDelay(pdMS_TO_TICKS((secondsUntilNextMinute * 1000))); + + esp_timer_start_periodic(minuteTimer, usPerMinute); + + WorkItem timeUpdate = {TASK_TIME_UPDATE, 0}; + xQueueSend(workQueue, &timeUpdate, portMAX_DELAY); + // xTaskNotifyGive(timeUpdateTaskHandle); + + vTaskDelete(NULL); +} + +void setupScreenRotateTimer(void *pvParameters) { + const esp_timer_create_args_t screenRotateTimerConfig = { + .callback = &screenRotateTimerISR, .name = "screen_rotate_timer"}; + + esp_timer_create(&screenRotateTimerConfig, &screenRotateTimer); + + if (preferences.getBool("timerActive", true)) { + esp_timer_start_periodic(screenRotateTimer, + getTimerSeconds() * usPerSecond); + } + + vTaskDelete(NULL); +} + +uint getTimerSeconds() { return preferences.getUInt("timerSeconds", 1800); } + +bool isTimerActive() { return esp_timer_is_active(screenRotateTimer); } + +void setTimerActive(bool status) { + if (status) { + esp_timer_start_periodic(screenRotateTimer, + getTimerSeconds() * usPerSecond); + queueLedEffect(LED_EFFECT_START_TIMER); + preferences.putBool("timerActive", true); + } else { + esp_timer_stop(screenRotateTimer); + queueLedEffect(LED_EFFECT_PAUSE_TIMER); + preferences.putBool("timerActive", false); + } + + if (eventSourceTaskHandle != NULL) xTaskNotifyGive(eventSourceTaskHandle); +} + +void toggleTimerActive() { setTimerActive(!isTimerActive()); } + +uint getCurrentScreen() { return currentScreen; } + +void setCurrentScreen(uint newScreen) { + if (newScreen != SCREEN_CUSTOM) { + preferences.putUInt("currentScreen", newScreen); + } + + currentScreen = newScreen; + + switch (currentScreen) { + case SCREEN_TIME: { + WorkItem timeUpdate = {TASK_TIME_UPDATE, 0}; + xQueueSend(workQueue, &timeUpdate, portMAX_DELAY); + // xTaskNotifyGive(timeUpdateTaskHandle); + break; + } + case SCREEN_HALVING_COUNTDOWN: + case SCREEN_BLOCK_HEIGHT: { + WorkItem blockUpdate = {TASK_BLOCK_UPDATE, 0}; + xQueueSend(workQueue, &blockUpdate, portMAX_DELAY); + // xTaskNotifyGive(blockUpdateTaskHandle); + break; + } + case SCREEN_MARKET_CAP: + case SCREEN_MSCW_TIME: + case SCREEN_BTC_TICKER: { + WorkItem priceUpdate = {TASK_PRICE_UPDATE, 0}; + xQueueSend(workQueue, &priceUpdate, portMAX_DELAY); + // xTaskNotifyGive(priceUpdateTaskHandle); + break; + } + case SCREEN_BLOCK_FEE_RATE: { + WorkItem blockUpdate = {TASK_FEE_UPDATE, 0}; + xQueueSend(workQueue, &blockUpdate, portMAX_DELAY); + break; + } + } + + if (eventSourceTaskHandle != NULL) xTaskNotifyGive(eventSourceTaskHandle); +} + +void nextScreen() { + int newCurrentScreen = (getCurrentScreen() + 1) % SCREEN_COUNT; + String key = "screen" + String(newCurrentScreen) + "Visible"; + + while (!preferences.getBool(key.c_str(), true)) { + newCurrentScreen = (newCurrentScreen + 1) % SCREEN_COUNT; + key = "screen" + String(newCurrentScreen) + "Visible"; + } + setCurrentScreen(newCurrentScreen); +} + +void previousScreen() { + int newCurrentScreen = modulo(getCurrentScreen() - 1, SCREEN_COUNT); + String key = "screen" + String(newCurrentScreen) + "Visible"; + + while (!preferences.getBool(key.c_str(), true)) { + newCurrentScreen = modulo(newCurrentScreen - 1, SCREEN_COUNT); + key = "screen" + String(newCurrentScreen) + "Visible"; + } + setCurrentScreen(newCurrentScreen); +} + +void showSystemStatusScreen() { + std::array sysStatusEpdContent = {"", "", "", "", + "", "", ""}; + + String ipAddr = WiFi.localIP().toString(); + String subNet = WiFi.subnetMask().toString(); + + sysStatusEpdContent[0] = "IP/Subnet"; + + int ipAddrPos = 0; + int subnetPos = 0; + for (int i = 0; i < 4; i++) { + sysStatusEpdContent[1 + i] = ipAddr.substring(0, ipAddr.indexOf('.')) + + "/" + subNet.substring(0, subNet.indexOf('.')); + ipAddrPos = ipAddr.indexOf('.') + 1; + subnetPos = subNet.indexOf('.') + 1; + ipAddr = ipAddr.substring(ipAddrPos); + subNet = subNet.substring(subnetPos); + } + sysStatusEpdContent[NUM_SCREENS - 2] = "RAM/Status"; + + sysStatusEpdContent[NUM_SCREENS - 1] = + String((int)round(ESP.getFreeHeap() / 1024)) + "/" + + (int)round(ESP.getHeapSize() / 1024); + setCurrentScreen(SCREEN_CUSTOM); + setEpdContent(sysStatusEpdContent); } \ No newline at end of file diff --git a/src/lib/screen_handler.hpp b/src/lib/screen_handler.hpp index 914af09..6cbb2d0 100644 --- a/src/lib/screen_handler.hpp +++ b/src/lib/screen_handler.hpp @@ -5,25 +5,27 @@ #include #include -#include -#include "lib/mining_pool/mining_pool_stats_handler.hpp" #include "lib/epd.hpp" +#include "lib/price_fetch.hpp" #include "lib/shared.hpp" -#define WORK_QUEUE_SIZE 10 - +// extern TaskHandle_t priceUpdateTaskHandle; +// extern TaskHandle_t blockUpdateTaskHandle; +// extern TaskHandle_t timeUpdateTaskHandle; extern TaskHandle_t workerTaskHandle; extern TaskHandle_t taskScreenRotateTaskHandle; + +extern esp_timer_handle_t screenRotateTimer; +extern esp_timer_handle_t minuteTimer; + extern QueueHandle_t workQueue; typedef enum { TASK_PRICE_UPDATE, TASK_BLOCK_UPDATE, TASK_FEE_UPDATE, - TASK_TIME_UPDATE, - TASK_BITAXE_UPDATE, - TASK_MINING_POOL_STATS_UPDATE + TASK_TIME_UPDATE } TaskType; typedef struct { @@ -31,26 +33,28 @@ typedef struct { char data; } WorkItem; -class ScreenHandler { -private: - static uint currentScreen; - static uint currentCurrency; - -public: - static uint getCurrentScreen() { return currentScreen; } - static uint getCurrentCurrency() { return currentCurrency; } - static void setCurrentScreen(uint newScreen); - static void setCurrentCurrency(char currency); - static void nextScreen(); - static void previousScreen(); - static void showSystemStatusScreen(); - static bool isCurrencySpecific(uint screen); - static bool handleCurrencyRotation(bool forward); - static int findNextVisibleScreen(int currentScreen, bool forward); -}; - -// Keep as free functions since they deal with FreeRTOS tasks void workerTask(void *pvParameters); +uint getCurrentScreen(); +void setCurrentScreen(uint newScreen); +void nextScreen(); +void previousScreen(); + +void showSystemStatusScreen(); + +void setupTimeUpdateTimer(void *pvParameters); +void setupScreenRotateTimer(void *pvParameters); + +void IRAM_ATTR minuteTimerISR(void *arg); +void IRAM_ATTR screenRotateTimerISR(void *arg); + +// void taskPriceUpdate(void *pvParameters); +// void taskBlockUpdate(void *pvParameters); +// void taskTimeUpdate(void *pvParameters); void taskScreenRotate(void *pvParameters); + +uint getTimerSeconds(); +bool isTimerActive(); +void setTimerActive(bool status); +void toggleTimerActive(); + void setupTasks(); -void cleanup(); \ No newline at end of file diff --git a/src/lib/shared.cpp b/src/lib/shared.cpp deleted file mode 100644 index b8efc0c..0000000 --- a/src/lib/shared.cpp +++ /dev/null @@ -1,183 +0,0 @@ -#include "shared.hpp" - -// const char *github_root_ca = -// "-----BEGIN CERTIFICATE-----\n" -// "MIICjzCCAhWgAwIBAgIQXIuZxVqUxdJxVt7NiYDMJjAKBggqhkjOPQQDAzCBiDEL\n" -// "MAkGA1UEBhMCVVMxEzARBgNVBAgTCk5ldyBKZXJzZXkxFDASBgNVBAcTC0plcnNl\n" -// "eSBDaXR5MR4wHAYDVQQKExVUaGUgVVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNVBAMT\n" -// "JVVTRVJUcnVzdCBFQ0MgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMTAwMjAx\n" -// "MDAwMDAwWhcNMzgwMTE4MjM1OTU5WjCBiDELMAkGA1UEBhMCVVMxEzARBgNVBAgT\n" -// "Ck5ldyBKZXJzZXkxFDASBgNVBAcTC0plcnNleSBDaXR5MR4wHAYDVQQKExVUaGUg\n" -// "VVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNVBAMTJVVTRVJUcnVzdCBFQ0MgQ2VydGlm\n" -// "aWNhdGlvbiBBdXRob3JpdHkwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAQarFRaqflo\n" -// "I+d61SRvU8Za2EurxtW20eZzca7dnNYMYf3boIkDuAUU7FfO7l0/4iGzzvfUinng\n" -// "o4N+LZfQYcTxmdwlkWOrfzCjtHDix6EznPO/LlxTsV+zfTJ/ijTjeXmjQjBAMB0G\n" -// "A1UdDgQWBBQ64QmG1M8ZwpZ2dEl23OA1xmNjmjAOBgNVHQ8BAf8EBAMCAQYwDwYD\n" -// "VR0TAQH/BAUwAwEB/zAKBggqhkjOPQQDAwNoADBlAjA2Z6EWCNzklwBBHU6+4WMB\n" -// "zzuqQhFkoJ2UOQIReVx7Hfpkue4WQrO/isIJxOzksU0CMQDpKmFHjFJKS04YcPbW\n" -// "RNZu9YO6bVi9JNlWSOrvxKJGgYhqOkbRqZtNyWHa0V1Xahg=\n" -// "-----END CERTIFICATE-----\n" -// "-----BEGIN CERTIFICATE-----\n" -// "MIIDjjCCAnagAwIBAgIQAzrx5qcRqaC7KGSxHQn65TANBgkqhkiG9w0BAQsFADBh\n" -// "MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3\n" -// "d3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBH\n" -// "MjAeFw0xMzA4MDExMjAwMDBaFw0zODAxMTUxMjAwMDBaMGExCzAJBgNVBAYTAlVT\n" -// "MRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5j\n" -// "b20xIDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IEcyMIIBIjANBgkqhkiG\n" -// "9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuzfNNNx7a8myaJCtSnX/RrohCgiN9RlUyfuI\n" -// "2/Ou8jqJkTx65qsGGmvPrC3oXgkkRLpimn7Wo6h+4FR1IAWsULecYxpsMNzaHxmx\n" -// "1x7e/dfgy5SDN67sH0NO3Xss0r0upS/kqbitOtSZpLYl6ZtrAGCSYP9PIUkY92eQ\n" -// "q2EGnI/yuum06ZIya7XzV+hdG82MHauVBJVJ8zUtluNJbd134/tJS7SsVQepj5Wz\n" -// "tCO7TG1F8PapspUwtP1MVYwnSlcUfIKdzXOS0xZKBgyMUNGPHgm+F6HmIcr9g+UQ\n" -// "vIOlCsRnKPZzFBQ9RnbDhxSJITRNrw9FDKZJobq7nMWxM4MphQIDAQABo0IwQDAP\n" -// "BgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBhjAdBgNVHQ4EFgQUTiJUIBiV\n" -// "5uNu5g/6+rkS7QYXjzkwDQYJKoZIhvcNAQELBQADggEBAGBnKJRvDkhj6zHd6mcY\n" -// "1Yl9PMWLSn/pvtsrF9+wX3N3KjITOYFnQoQj8kVnNeyIv/iPsGEMNKSuIEyExtv4\n" -// "NeF22d+mQrvHRAiGfzZ0JFrabA0UWTW98kndth/Jsw1HKj2ZL7tcu7XUIOGZX1NG\n" -// "Fdtom/DzMNU+MeKNhJ7jitralj41E6Vf8PlwUHBHQRFXGU7Aj64GxJUTFy8bJZ91\n" -// "8rGOmaFvE7FBcf6IKshPECBV1/MUReXgRPTqh5Uykw7+U0b6LJ3/iyK5S9kJRaTe\n" -// "pLiaWN0bfVKfjllDiIGknibVb63dDcY3fe0Dkhvld1927jyNxF1WW6LZZm6zNTfl\n" -// "MrY=\n" -// "-----END CERTIFICATE-----\n"; - -// const char* isrg_root_x1cert = R"EOF( -// -----BEGIN CERTIFICATE----- -// MIIFazCCA1OgAwIBAgIRAIIQz7DSQONZRGPgu2OCiwAwDQYJKoZIhvcNAQELBQAw -// TzELMAkGA1UEBhMCVVMxKTAnBgNVBAoTIEludGVybmV0IFNlY3VyaXR5IFJlc2Vh -// cmNoIEdyb3VwMRUwEwYDVQQDEwxJU1JHIFJvb3QgWDEwHhcNMTUwNjA0MTEwNDM4 -// WhcNMzUwNjA0MTEwNDM4WjBPMQswCQYDVQQGEwJVUzEpMCcGA1UEChMgSW50ZXJu -// ZXQgU2VjdXJpdHkgUmVzZWFyY2ggR3JvdXAxFTATBgNVBAMTDElTUkcgUm9vdCBY -// MTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAK3oJHP0FDfzm54rVygc -// h77ct984kIxuPOZXoHj3dcKi/vVqbvYATyjb3miGbESTtrFj/RQSa78f0uoxmyF+ -// 0TM8ukj13Xnfs7j/EvEhmkvBioZxaUpmZmyPfjxwv60pIgbz5MDmgK7iS4+3mX6U -// A5/TR5d8mUgjU+g4rk8Kb4Mu0UlXjIB0ttov0DiNewNwIRt18jA8+o+u3dpjq+sW -// T8KOEUt+zwvo/7V3LvSye0rgTBIlDHCNAymg4VMk7BPZ7hm/ELNKjD+Jo2FR3qyH -// B5T0Y3HsLuJvW5iB4YlcNHlsdu87kGJ55tukmi8mxdAQ4Q7e2RCOFvu396j3x+UC -// B5iPNgiV5+I3lg02dZ77DnKxHZu8A/lJBdiB3QW0KtZB6awBdpUKD9jf1b0SHzUv -// KBds0pjBqAlkd25HN7rOrFleaJ1/ctaJxQZBKT5ZPt0m9STJEadao0xAH0ahmbWn -// OlFuhjuefXKnEgV4We0+UXgVCwOPjdAvBbI+e0ocS3MFEvzG6uBQE3xDk3SzynTn -// jh8BCNAw1FtxNrQHusEwMFxIt4I7mKZ9YIqioymCzLq9gwQbooMDQaHWBfEbwrbw -// qHyGO0aoSCqI3Haadr8faqU9GY/rOPNk3sgrDQoo//fb4hVC1CLQJ13hef4Y53CI -// rU7m2Ys6xt0nUW7/vGT1M0NPAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNV -// HRMBAf8EBTADAQH/MB0GA1UdDgQWBBR5tFnme7bl5AFzgAiIyBpY9umbbjANBgkq -// hkiG9w0BAQsFAAOCAgEAVR9YqbyyqFDQDLHYGmkgJykIrGF1XIpu+ILlaS/V9lZL -// ubhzEFnTIZd+50xx+7LSYK05qAvqFyFWhfFQDlnrzuBZ6brJFe+GnY+EgPbk6ZGQ -// 3BebYhtF8GaV0nxvwuo77x/Py9auJ/GpsMiu/X1+mvoiBOv/2X/qkSsisRcOj/KK -// NFtY2PwByVS5uCbMiogziUwthDyC3+6WVwW6LLv3xLfHTjuCvjHIInNzktHCgKQ5 -// ORAzI4JMPJ+GslWYHb4phowim57iaztXOoJwTdwJx4nLCgdNbOhdjsnvzqvHu7Ur -// TkXWStAmzOVyyghqpZXjFaH3pO3JLF+l+/+sKAIuvtd7u+Nxe5AW0wdeRlN8NwdC -// jNPElpzVmbUq4JUagEiuTDkHzsxHpFKVK7q4+63SM1N95R1NbdWhscdCb+ZAJzVc -// oyi3B43njTOQ5yOf+1CceWxG1bQVs5ZufpsMljq4Ui0/1lvh+wjChP4kqKOJ2qxq -// 4RgqsahDYVvTH9w7jXbyLeiNdd8XM2w9U/t7y0Ff/9yi0GE44Za4rF2LN9d11TPA -// mRGunUHBcnWEvgJBQl9nJEiU0Zsnvgc/ubhPgXRR4Xq37Z0j4r7g1SgEEzwxA57d -// emyPxgcYxn/eR44/KJ4EBs+lVDR3veyJm+kXQ99b21/+jh5Xos1AnX5iItreGCc= -// -----END CERTIFICATE----- -// )EOF"; - - -#ifdef TEST_SCREENS -uint8_t input_buffer[3 * input_buffer_pixels]; // up to depth 24 -uint8_t output_row_mono_buffer[max_row_width / 8]; // buffer for at least one row of b/w bits -uint8_t output_row_color_buffer[max_row_width / 8]; // buffer for at least one row of color bits -uint8_t mono_palette_buffer[max_palette_pixels / 8]; // palette buffer for depth <= 8 b/w -uint8_t color_palette_buffer[max_palette_pixels / 8]; // palette buffer for depth <= 8 c/w -uint16_t rgb_palette_buffer[max_palette_pixels]; // palette buffer for depth <= 8 for buffered graphics, needed for 7-color display -#endif - -// Function to calculate SHA-256 hash -String calculateSHA256(uint8_t *data, size_t len) -{ - byte shaResult[32]; - mbedtls_md_context_t ctx; - mbedtls_md_type_t md_type = MBEDTLS_MD_SHA256; - - mbedtls_md_init(&ctx); - mbedtls_md_setup(&ctx, mbedtls_md_info_from_type(md_type), 0); - mbedtls_md_starts(&ctx); - mbedtls_md_update(&ctx, data, len); - mbedtls_md_finish(&ctx, shaResult); - mbedtls_md_free(&ctx); - - char sha256_str[65]; - for (int i = 0; i < 32; i++) - { - sprintf(sha256_str + (i * 2), "%02x", shaResult[i]); - } - sha256_str[64] = 0; - - return String(sha256_str); -} - -String calculateSHA256(WiFiClient *stream, size_t contentLength) { - mbedtls_md_context_t ctx; - mbedtls_md_type_t md_type = MBEDTLS_MD_SHA256; - - mbedtls_md_init(&ctx); - mbedtls_md_setup(&ctx, mbedtls_md_info_from_type(md_type), 0); - mbedtls_md_starts(&ctx); - - uint8_t buff[1024]; - size_t bytesRead = 0; - - while (bytesRead < contentLength) { - size_t toRead = min((size_t)(contentLength - bytesRead), sizeof(buff)); - size_t readBytes = stream->readBytes(buff, toRead); - - if (readBytes == 0) { - break; - } - - mbedtls_md_update(&ctx, buff, readBytes); - bytesRead += readBytes; - } - - byte shaResult[32]; - mbedtls_md_finish(&ctx, shaResult); - mbedtls_md_free(&ctx); - - String result = ""; - for (int i = 0; i < sizeof(shaResult); i++) { - char str[3]; - sprintf(str, "%02x", (int)shaResult[i]); - result += str; - } - - return result; -} - -// uint8_t* getOceanIcon() { -// zlib_turbo zt; -// int iUncompSize = zt.gzip_info((uint8_t *)ocean_logo_comp, ocean_logo_size); -// uint8_t *pUncompressed; -// pUncompressed = (uint8_t *)malloc(iUncompSize+4); -// zt.gunzip((uint8_t *)ocean_logo_comp, ocean_logo_size, pUncompressed); -// } - -WiFiClientSecure HttpHelper::secureClient; -WiFiClient HttpHelper::insecureClient; -bool HttpHelper::certBundleSet = false; - -HTTPClient* HttpHelper::begin(const String& url) { - HTTPClient* http = new HTTPClient(); - - if (url.startsWith("https://")) { - if (!certBundleSet) { - secureClient.setCACertBundle(rootca_crt_bundle_start); - certBundleSet = true; - } - http->begin(secureClient, url); - } else { - http->begin(insecureClient, url); - } - - http->setUserAgent(USER_AGENT); - return http; -} - -void HttpHelper::end(HTTPClient* http) { - if (http) { - http->end(); - delete http; - } -} - diff --git a/src/lib/shared.hpp b/src/lib/shared.hpp index 97af754..65e1009 100644 --- a/src/lib/shared.hpp +++ b/src/lib/shared.hpp @@ -1,31 +1,19 @@ #pragma once -#include "MCP23017.h" -// #include +#include #include -#include #include #include #include #include #include -#include -#include "esp_crt_bundle.h" -#include -#include #include #include -#include -#include -#include "defaults.hpp" - -#define USER_AGENT "BTClock/3.0" - -extern MCP23017 mcp1; -#ifdef IS_BTCLOCK_V8 -extern MCP23017 mcp2; +extern Adafruit_MCP23X17 mcp1; +#ifdef IS_BTCLOCK_S3 +extern Adafruit_MCP23X17 mcp2; #endif extern Preferences preferences; extern std::mutex mcpMutex; @@ -39,87 +27,33 @@ extern std::mutex mcpMutex; #endif const PROGMEM int SCREEN_BLOCK_HEIGHT = 0; - +const PROGMEM int SCREEN_MSCW_TIME = 1; +const PROGMEM int SCREEN_BTC_TICKER = 2; const PROGMEM int SCREEN_TIME = 3; const PROGMEM int SCREEN_HALVING_COUNTDOWN = 4; +const PROGMEM int SCREEN_MARKET_CAP = 5; const PROGMEM int SCREEN_BLOCK_FEE_RATE = 6; -const PROGMEM int SCREEN_SATS_PER_CURRENCY = 10; - -const PROGMEM int SCREEN_BTC_TICKER = 20; - -const PROGMEM int SCREEN_MARKET_CAP = 30; - -const PROGMEM int SCREEN_MINING_POOL_STATS_HASHRATE = 70; -const PROGMEM int SCREEN_MINING_POOL_STATS_EARNINGS = 71; - -const PROGMEM int SCREEN_BITAXE_HASHRATE = 80; -const PROGMEM int SCREEN_BITAXE_BESTDIFF = 81; - - const PROGMEM int SCREEN_COUNTDOWN = 98; const PROGMEM int SCREEN_CUSTOM = 99; const int SCREEN_COUNT = 7; const PROGMEM int screens[SCREEN_COUNT] = { - SCREEN_BLOCK_HEIGHT, SCREEN_SATS_PER_CURRENCY, SCREEN_BTC_TICKER, + SCREEN_BLOCK_HEIGHT, SCREEN_MSCW_TIME, SCREEN_BTC_TICKER, SCREEN_TIME, SCREEN_HALVING_COUNTDOWN, SCREEN_MARKET_CAP, SCREEN_BLOCK_FEE_RATE}; const int usPerSecond = 1000000; const int usPerMinute = 60 * usPerSecond; -const int msPerSecond = 1000; -// extern const char *github_root_ca; -// extern const char *isrg_root_x1cert; +struct SpiRamAllocator : ArduinoJson::Allocator { + void* allocate(size_t size) override { + return heap_caps_malloc(size, MALLOC_CAP_SPIRAM); + } -extern const uint8_t rootca_crt_bundle_start[] asm("_binary_x509_crt_bundle_start"); -// extern const uint8_t ocean_logo_comp[] asm("_binary_ocean_gz_start"); -// extern const uint8_t ocean_logo_comp_end[] asm("_binary_ocean_gz_end"); - -// uint8_t* getOceanIcon(); - -// const size_t ocean_logo_size = ocean_logo_comp_end - ocean_logo_comp; - -const PROGMEM char UPDATE_FIRMWARE = U_FLASH; -const PROGMEM char UPDATE_WEBUI = U_SPIFFS; -const PROGMEM char UPDATE_ALL = 99; - -struct ScreenMapping { - int value; - const char* name; -}; - -String calculateSHA256(uint8_t* data, size_t len); -String calculateSHA256(WiFiClient *stream, size_t contentLength); - -namespace ArduinoJson { - template - struct Converter> { - static void toJson(const std::vector& src, JsonVariant dst) { - JsonArray array = dst.to(); - for (T item : src) - array.add(item); - } - }; - - template - struct Converter> { - static void toJson(const std::array& src, JsonVariant dst) { - JsonArray array = dst.to(); - for (const String& item : src) { - array.add(item); - } - } - }; -} - -class HttpHelper { -public: - static HTTPClient* begin(const String& url); - static void end(HTTPClient* http); - -private: - static WiFiClientSecure secureClient; - static bool certBundleSet; - static WiFiClient insecureClient; -}; + void deallocate(void* pointer) override { + heap_caps_free(pointer); + } + void* reallocate(void* ptr, size_t new_size) override { + return heap_caps_realloc(ptr, new_size, MALLOC_CAP_SPIRAM); + } +}; \ No newline at end of file diff --git a/src/lib/timers.cpp b/src/lib/timers.cpp deleted file mode 100644 index 850ead3..0000000 --- a/src/lib/timers.cpp +++ /dev/null @@ -1,93 +0,0 @@ -#include "timers.hpp" -#include "led_handler.hpp" - -esp_timer_handle_t screenRotateTimer; -esp_timer_handle_t minuteTimer; - -void setupTimeUpdateTimer(void *pvParameters) { - const esp_timer_create_args_t minuteTimerConfig = { - .callback = &minuteTimerISR, .name = "minute_timer"}; - - esp_timer_create(&minuteTimerConfig, &minuteTimer); - - time_t currentTime; - struct tm timeinfo; - time(¤tTime); - localtime_r(¤tTime, &timeinfo); - uint32_t secondsUntilNextMinute = 60 - timeinfo.tm_sec; - - if (secondsUntilNextMinute > 0) - vTaskDelay(pdMS_TO_TICKS((secondsUntilNextMinute * 1000))); - - esp_timer_start_periodic(minuteTimer, usPerMinute); - - WorkItem timeUpdate = {TASK_TIME_UPDATE, 0}; - xQueueSend(workQueue, &timeUpdate, portMAX_DELAY); - // xTaskNotifyGive(timeUpdateTaskHandle); - - vTaskDelete(NULL); -} - -void setupScreenRotateTimer(void *pvParameters) { - const esp_timer_create_args_t screenRotateTimerConfig = { - .callback = &screenRotateTimerISR, .name = "screen_rotate_timer"}; - - esp_timer_create(&screenRotateTimerConfig, &screenRotateTimer); - - if (preferences.getBool("timerActive", DEFAULT_TIMER_ACTIVE)) { - esp_timer_start_periodic(screenRotateTimer, - getTimerSeconds() * usPerSecond); - } - - vTaskDelete(NULL); -} - -uint getTimerSeconds() { return preferences.getUInt("timerSeconds", DEFAULT_TIMER_SECONDS); } - -bool isTimerActive() { return esp_timer_is_active(screenRotateTimer); } - -void setTimerActive(bool status) { - if (status) { - esp_timer_start_periodic(screenRotateTimer, - getTimerSeconds() * usPerSecond); - getLedHandler().queueEffect(LED_EFFECT_START_TIMER); - preferences.putBool("timerActive", true); - } else { - esp_timer_stop(screenRotateTimer); - getLedHandler().queueEffect(LED_EFFECT_PAUSE_TIMER); - preferences.putBool("timerActive", false); - } - - if (eventSourceTaskHandle != NULL) xTaskNotifyGive(eventSourceTaskHandle); -} - -void toggleTimerActive() { setTimerActive(!isTimerActive()); } - -void IRAM_ATTR minuteTimerISR(void *arg) { - BaseType_t xHigherPriorityTaskWoken = pdFALSE; - // vTaskNotifyGiveFromISR(timeUpdateTaskHandle, &xHigherPriorityTaskWoken); - WorkItem timeUpdate = {TASK_TIME_UPDATE, 0}; - xQueueSendFromISR(workQueue, &timeUpdate, &xHigherPriorityTaskWoken); - - TaskHandle_t bitaxeHandle = BitAxeFetch::getInstance().getTaskHandle(); - if (bitaxeHandle != NULL) { - vTaskNotifyGiveFromISR(bitaxeHandle, &xHigherPriorityTaskWoken); - } - - TaskHandle_t miningPoolHandle = MiningPoolStatsFetch::getInstance().getTaskHandle(); - if (miningPoolHandle != NULL) { - vTaskNotifyGiveFromISR(miningPoolHandle, &xHigherPriorityTaskWoken); - } - - if (xHigherPriorityTaskWoken == pdTRUE) { - portYIELD_FROM_ISR(); - } -} - -void IRAM_ATTR screenRotateTimerISR(void *arg) { - BaseType_t xHigherPriorityTaskWoken = pdFALSE; - vTaskNotifyGiveFromISR(taskScreenRotateTaskHandle, &xHigherPriorityTaskWoken); - if (xHigherPriorityTaskWoken == pdTRUE) { - portYIELD_FROM_ISR(); - } -} \ No newline at end of file diff --git a/src/lib/timers.hpp b/src/lib/timers.hpp deleted file mode 100644 index e543a9f..0000000 --- a/src/lib/timers.hpp +++ /dev/null @@ -1,22 +0,0 @@ -#pragma once - -#include -#include -#include - -#include "lib/shared.hpp" -#include "lib/screen_handler.hpp" - -extern esp_timer_handle_t screenRotateTimer; -extern esp_timer_handle_t minuteTimer; - -void setupTimeUpdateTimer(void *pvParameters); -void setupScreenRotateTimer(void *pvParameters); - -void IRAM_ATTR minuteTimerISR(void *arg); -void IRAM_ATTR screenRotateTimerISR(void *arg); - -uint getTimerSeconds(); -bool isTimerActive(); -void setTimerActive(bool status); -void toggleTimerActive(); \ No newline at end of file diff --git a/src/lib/v2_notify.cpp b/src/lib/v2_notify.cpp deleted file mode 100644 index b915518..0000000 --- a/src/lib/v2_notify.cpp +++ /dev/null @@ -1,189 +0,0 @@ -#include "v2_notify.hpp" - -using namespace V2Notify; - -namespace V2Notify -{ - WebSocketsClient webSocket; - - TaskHandle_t v2NotifyTaskHandle; - - String currentHostname; - - void setupV2Notify() - { - String hostname = "ws.btclock.dev"; - if (getDataSource() == CUSTOM_SOURCE) - { - Serial.println(F("Connecting to custom source")); - hostname = preferences.getString("ceEndpoint", DEFAULT_CUSTOM_ENDPOINT); - bool useSSL = !preferences.getBool("ceDisableSSL", DEFAULT_CUSTOM_ENDPOINT_DISABLE_SSL); - - if (useSSL) { - webSocket.beginSSL(hostname, 443, "/api/v2/ws"); - } else { - webSocket.begin(hostname, 80, "/api/v2/ws"); - } - } - else - { - Serial.println(F("Connecting to V2 source")); - webSocket.beginSSL(hostname, 443, "/api/v2/ws"); - } - - webSocket.onEvent(V2Notify::onWebsocketV2Event); - webSocket.setReconnectInterval(5000); - webSocket.enableHeartbeat(15000, 3000, 2); - - V2Notify::setupV2NotifyTask(); - - currentHostname = hostname; - } - - void onWebsocketV2Event(WStype_t type, uint8_t *payload, size_t length) - { - switch (type) - { - case WStype_DISCONNECTED: - Serial.print(F("[WSc] Disconnected!\n")); - break; - case WStype_CONNECTED: - { - Serial.print(F("[WSc] Connected to ")); - Serial.print(currentHostname); - Serial.print(F(": ")); - Serial.println((char *)payload); - - JsonDocument response; - - response["type"] = "subscribe"; - response["eventType"] = "blockfee"; - size_t responseLength = measureMsgPack(response); - uint8_t *buffer = new uint8_t[responseLength]; - serializeMsgPack(response, buffer, responseLength); - webSocket.sendBIN(buffer, responseLength); - delete[] buffer; - - buffer = new uint8_t[responseLength]; - - response["type"] = "subscribe"; - response["eventType"] = "blockheight"; - responseLength = measureMsgPack(response); - buffer = new uint8_t[responseLength]; - serializeMsgPack(response, buffer, responseLength); - webSocket.sendBIN(buffer, responseLength); - - delete[] buffer; - - buffer = new uint8_t[responseLength]; - - response["type"] = "subscribe"; - response["eventType"] = "price"; - - JsonArray currenciesArray = response["currencies"].to(); - - for (const auto &str : getActiveCurrencies()) - { - currenciesArray.add(str); - } - - // response["currencies"] = currenciesArray; - responseLength = measureMsgPack(response); - buffer = new uint8_t[responseLength]; - serializeMsgPack(response, buffer, responseLength); - webSocket.sendBIN(buffer, responseLength); - break; - } - case WStype_TEXT: - Serial.print(F("[WSc] get text: ")); - Serial.println((char *)payload); - - // send message to server - // webSocket.sendTXT("message here"); - break; - case WStype_BIN: - { - JsonDocument doc; - DeserializationError error = deserializeMsgPack(doc, payload, length); - - if (error) { - Serial.println(F("Error deserializing message")); - break; - } - - V2Notify::handleV2Message(doc); - break; - } - case WStype_ERROR: - case WStype_FRAGMENT_TEXT_START: - case WStype_FRAGMENT_BIN_START: - case WStype_FRAGMENT: - case WStype_PING: - case WStype_PONG: - case WStype_FRAGMENT_FIN: - break; - } - } - - void handleV2Message(JsonDocument doc) - { - if (doc["blockheight"].is()) - { - uint newBlockHeight = doc["blockheight"].as(); - - if (newBlockHeight == BlockNotify::getInstance().getBlockHeight()) - { - return; - } - - if (debugLogEnabled()) { - Serial.print(F("processNewBlock ")); - Serial.println(newBlockHeight); - } - BlockNotify::getInstance().processNewBlock(newBlockHeight); - } - else if (doc["blockfee"].is()) - { - uint medianFee = doc["blockfee"].as(); - - if (debugLogEnabled()) { - Serial.print(F("processNewBlockFee ")); - Serial.println(medianFee); - } - - BlockNotify::getInstance().processNewBlockFee(medianFee); - } - else if (doc["price"].is()) - { - - // Iterate through the key-value pairs of the "price" object - for (JsonPair kv : doc["price"].as()) - { - const char *currency = kv.key().c_str(); - uint newPrice = kv.value().as(); - - processNewPrice(newPrice, getCurrencyChar(currency)); - } - } - } - - void taskV2Notify(void *pvParameters) - { - for (;;) - { - webSocket.loop(); - vTaskDelay(pdMS_TO_TICKS(10)); - } - } - - void setupV2NotifyTask() - { - xTaskCreate(V2Notify::taskV2Notify, "v2Notify", (6 * 1024), NULL, tskIDLE_PRIORITY, - &V2Notify::v2NotifyTaskHandle); - } - - bool isV2NotifyConnected() - { - return webSocket.isConnected(); - } -} \ No newline at end of file diff --git a/src/lib/v2_notify.hpp b/src/lib/v2_notify.hpp deleted file mode 100644 index 21a74ba..0000000 --- a/src/lib/v2_notify.hpp +++ /dev/null @@ -1,26 +0,0 @@ -#pragma once - -#include -#include -#include -#include "block_notify.hpp" -#include - -#include "lib/screen_handler.hpp" - -namespace V2Notify { - extern TaskHandle_t v2NotifyTaskHandle; - - void setupV2NotifyTask(); - void taskV2Notify(void *pvParameters); - - void setupV2Notify(); - void onWebsocketV2Event(WStype_t type, uint8_t * payload, size_t length); - void handleV2Message(JsonDocument doc); - - bool isV2NotifyConnected(); -} -// void stopV2Notify(); -// void restartV2Notify(); -// bool getPriceNotifyInit(); -// uint getLastPriceUpdate(); \ No newline at end of file diff --git a/src/lib/webserver.cpp b/src/lib/webserver.cpp index 2d447d6..6255416 100644 --- a/src/lib/webserver.cpp +++ b/src/lib/webserver.cpp @@ -1,51 +1,23 @@ #include "webserver.hpp" -#include "lib/led_handler.hpp" -#include "lib/shared.hpp" - -static const char* JSON_CONTENT = "application/json"; - -static const char *const PROGMEM strSettings[] = { - "hostnamePrefix", "mempoolInstance", "nostrPubKey", "nostrRelay", "bitaxeHostname", "miningPoolName", "miningPoolUser", "nostrZapPubkey", "httpAuthUser", "httpAuthPass", "gitReleaseUrl", "poolLogosUrl", "ceEndpoint", "fontName", "localPoolEndpoint", "tzString"}; - -static const char *const PROGMEM uintSettings[] = {"minSecPriceUpd", "fullRefreshMin", "ledBrightness", "flMaxBrightness", "flEffectDelay", "luxLightToggle", "wpTimeout"}; - -static const char *const PROGMEM boolSettings[] = {"ledTestOnPower", "ledFlashOnUpd", - "mdnsEnabled", "otaEnabled", "stealFocus", - "mcapBigChar", "useSatsSymbol", "useBlkCountdown", - "suffixPrice", "disableLeds", - "mowMode", "suffixShareDot", "flOffWhenDark", - "flAlwaysOn", "flDisable", "flFlashOnUpd", - "mempoolSecure", "bitaxeEnabled", - "miningPoolStats", "verticalDesc", - "nostrZapNotify", "httpAuthEnabled", - "enableDebugLog", "ceDisableSSL", "dndEnabled", "dndTimeBasedEnabled", "scrnRestoreZap"}; AsyncWebServer server(80); AsyncEventSource events("/events"); TaskHandle_t eventSourceTaskHandle; -#define HTTP_OK 200 -#define HTTP_BAD_REQUEST 400 - -void setupWebserver() -{ - events.onConnect([](AsyncEventSourceClient *client) - { client->send("welcome", NULL, millis(), 1000); - }); +void setupWebserver() { + events.onConnect([](AsyncEventSourceClient *client) { + client->send("welcome", NULL, millis(), 1000); + }); server.addHandler(&events); - AsyncStaticWebHandler &staticHandler = server.serveStatic("/", LittleFS, "/").setDefaultFile("index.html"); + // server.serveStatic("/css", LittleFS, "/css/"); + server.serveStatic("/fonts", LittleFS, "/fonts/"); + server.serveStatic("/build", LittleFS, "/build"); + server.serveStatic("/swagger.json", LittleFS, "/swagger.json"); + server.serveStatic("/api.html", LittleFS, "/api.html"); - server.rewrite("/convert", "/"); - server.rewrite("/api", "/"); + server.on("/", HTTP_GET, onIndex); - if (preferences.getBool("httpAuthEnabled", DEFAULT_HTTP_AUTH_ENABLED)) - { - staticHandler.setAuthentication( - preferences.getString("httpAuthUser", DEFAULT_HTTP_AUTH_USERNAME), - preferences.getString("httpAuthPass", DEFAULT_HTTP_AUTH_PASSWORD)); - } - // server.on("/", HTTP_GET, onIndex); server.on("/api/status", HTTP_GET, onApiStatus); server.on("/api/system_status", HTTP_GET, onApiSystemStatus); server.on("/api/wifi_set_tx_power", HTTP_GET, onApiSetWifiTxPower); @@ -55,19 +27,16 @@ void setupWebserver() server.on("/api/stop_datasources", HTTP_GET, onApiStopDataSources); server.on("/api/restart_datasources", HTTP_GET, onApiRestartDataSources); + server.on("/api/action/pause", HTTP_GET, onApiActionPause); server.on("/api/action/timer_restart", HTTP_GET, onApiActionTimerRestart); server.on("/api/settings", HTTP_GET, onApiSettingsGet); + server.on("/api/settings", HTTP_POST, onApiSettingsPost); server.on("/api/show/screen", HTTP_GET, onApiShowScreen); - server.on("/api/show/currency", HTTP_GET, onApiShowCurrency); - server.on("/api/show/text", HTTP_GET, onApiShowText); - server.on("/api/screen/next", HTTP_GET, onApiScreenControl); - server.on("/api/screen/previous", HTTP_GET, onApiScreenControl); - AsyncCallbackJsonWebHandler *settingsPatchHandler = new AsyncCallbackJsonWebHandler("/api/json/settings", onApiSettingsPatch); server.addHandler(settingsPatchHandler); @@ -77,40 +46,18 @@ void setupWebserver() server.addHandler(handler); AsyncCallbackJsonWebHandler *lightsJsonHandler = - new AsyncCallbackJsonWebHandler("/api/lights/set", onApiLightsSetJson); + new AsyncCallbackJsonWebHandler("/api/lights", onApiLightsSetJson); server.addHandler(lightsJsonHandler); server.on("/api/lights/off", HTTP_GET, onApiLightsOff); server.on("/api/lights/color", HTTP_GET, onApiLightsSetColor); server.on("/api/lights", HTTP_GET, onApiLightsStatus); - server.on("/api/identify", HTTP_GET, onApiIdentify); - -#ifdef HAS_FRONTLIGHT - server.on("/api/frontlight/on", HTTP_GET, onApiFrontlightOn); - server.on("/api/frontlight/flash", HTTP_GET, onApiFrontlightFlash); - server.on("/api/frontlight/status", HTTP_GET, onApiFrontlightStatus); - - server.on("/api/frontlight/brightness", HTTP_GET, onApiFrontlightSetBrightness); - server.on("/api/frontlight/off", HTTP_GET, onApiFrontlightOff); - - server.addRewrite( - new OneParamRewrite("/api/frontlight/brightness/{b}", "/api/frontlight/brightness?b={b}")); -#endif // server.on("^\\/api\\/lights\\/([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$", HTTP_GET, // onApiLightsSetColor); - if (preferences.getBool("otaEnabled", DEFAULT_OTA_ENABLED)) - { - server.on("/upload/firmware", HTTP_POST, onFirmwareUpdate, asyncFirmwareUpdateHandler); - server.on("/upload/webui", HTTP_POST, onFirmwareUpdate, asyncWebuiUpdateHandler); - server.on("/api/firmware/auto_update", HTTP_GET, onAutoUpdateFirmware); - } - server.on("/api/restart", HTTP_GET, onApiRestart); - server.addRewrite( - new OneParamRewrite("/api/show/currency/{c}", "/api/show/currency?c={c}")); - server.addRewrite(new OneParamRewrite("/api/lights/color/{color}", + server.addRewrite(new OneParamRewrite("/api/lights/{color}", "/api/lights/color?c={color}")); server.addRewrite( new OneParamRewrite("/api/show/screen/{s}", "/api/show/screen?s={s}")); @@ -119,10 +66,6 @@ void setupWebserver() server.addRewrite(new OneParamRewrite("/api/show/number/{number}", "/api/show/text?t={text}")); - server.on("/api/dnd/status", HTTP_GET, onApiDNDStatus); - server.on("/api/dnd/enable", HTTP_POST, onApiDNDEnable); - server.on("/api/dnd/disable", HTTP_POST, onApiDNDDisable); - server.onNotFound(onNotFound); DefaultHeaders::Instance().addHeader("Access-Control-Allow-Origin", "*"); @@ -132,13 +75,10 @@ void setupWebserver() server.begin(); - if (preferences.getBool("mdnsEnabled", DEFAULT_MDNS_ENABLED)) - { - if (!MDNS.begin(getMyHostname())) - { + if (preferences.getBool("mdnsEnabled", true)) { + if (!MDNS.begin(getMyHostname())) { Serial.println(F("Error setting up MDNS responder!")); - while (1) - { + while (1) { delay(1000); } } @@ -146,7 +86,6 @@ void setupWebserver() MDNS.addServiceTxt("http", "tcp", "model", "BTClock"); MDNS.addServiceTxt("http", "tcp", "version", "3.0"); MDNS.addServiceTxt("http", "tcp", "rev", GIT_REV); - MDNS.addServiceTxt("http", "tcp", "hw_rev", getHwRev()); } xTaskCreate(eventSourceTask, "eventSourceTask", 4096, NULL, tskIDLE_PRIORITY, @@ -155,150 +94,42 @@ void setupWebserver() void stopWebServer() { server.end(); } -void onFirmwareUpdate(AsyncWebServerRequest *request) -{ - bool shouldReboot = !Update.hasError(); - AsyncWebServerResponse *response = request->beginResponse(200, "text/plain", shouldReboot ? "OK" : "FAIL"); - response->addHeader("Connection", "close"); - request->send(response); -} - -void onAutoUpdateFirmware(AsyncWebServerRequest *request) -{ - UpdateMessage msg = {UPDATE_ALL}; - if (xQueueSend(otaQueue, &msg, 0) == pdTRUE) - { - request->send(200, "application/json", "{\"msg\":\"Firmware update triggered\"}"); - } - else - { - request->send(503,"application/json", "{\"msg\":\"Update already in progress\"}"); - } -} - -void asyncWebuiUpdateHandler(AsyncWebServerRequest *request, String filename, size_t index, uint8_t *data, size_t len, bool final) -{ - asyncFileUpdateHandler(request, filename, index, data, len, final, U_SPIFFS); -} - -void asyncFileUpdateHandler(AsyncWebServerRequest *request, String filename, size_t index, uint8_t *data, size_t len, bool final, int command) -{ - if (!index) - { - Serial.printf("Update Start: %s\n", filename.c_str()); - - if (command == U_FLASH) - { - // Update.runAsync(true); - if (!Update.begin((ESP.getFreeSketchSpace() - 0x1000) & 0xFFFFF000), command) - { - Update.printError(Serial); - return; - } - } - else if (command == U_SPIFFS) - { - size_t fsSize = UPDATE_SIZE_UNKNOWN; // or specify the size of your filesystem partition - if (!Update.begin(fsSize, U_SPIFFS)) // or U_FS for LittleFS - { - Update.printError(Serial); - return; - } - } - } - if (!Update.hasError()) - { - if (Update.write(data, len) != len) - { - Update.printError(Serial); - } - } - if (final) - { - if (Update.end(true)) - { - Serial.printf("Update Success: %uB\n", index + len); - onApiRestart(request); - } - else - { - Update.printError(Serial); - } - } -} - -void asyncFirmwareUpdateHandler(AsyncWebServerRequest *request, String filename, size_t index, uint8_t *data, size_t len, bool final) -{ - asyncFileUpdateHandler(request, filename, index, data, len, final, U_FLASH); -} - -JsonDocument getStatusObject() -{ - auto& ledHandler = getLedHandler(); +JsonDocument getStatusObject() { JsonDocument root; - root["currentScreen"] = ScreenHandler::getCurrentScreen(); + root["currentScreen"] = getCurrentScreen(); root["numScreens"] = NUM_SCREENS; root["timerRunning"] = isTimerActive(); - root["isOTAUpdating"] = getIsOTAUpdating(); root["espUptime"] = esp_timer_get_time() / 1000000; + // root["currentPrice"] = getPrice(); + // root["currentBlockHeight"] = getBlockHeight(); root["espFreeHeap"] = ESP.getFreeHeap(); root["espHeapSize"] = ESP.getHeapSize(); + // root["espFreePsram"] = ESP.getFreePsram(); + // root["espPsramSize"] = ESP.getPsramSize(); JsonObject conStatus = root["connectionStatus"].to(); - conStatus["price"] = isPriceNotifyConnected(); - auto& blockNotify = BlockNotify::getInstance(); - conStatus["blocks"] = blockNotify.isConnected(); - conStatus["V2"] = V2Notify::isV2NotifyConnected(); - conStatus["nostr"] = nostrConnected(); + conStatus["blocks"] = isBlockNotifyConnected(); root["rssi"] = WiFi.RSSI(); - root["currency"] = getCurrencyCode(ScreenHandler::getCurrentCurrency()); -#ifdef HAS_FRONTLIGHT - std::vector statuses = ledHandler.frontlightGetStatus(); - uint16_t arr[NUM_SCREENS]; - std::copy(statuses.begin(), statuses.end(), arr); - - JsonArray data = root["flStatus"].to(); - copyArray(arr, data); - - if (hasLightLevel()) - { - root["lightLevel"] = getLightLevel(); - } -#endif - - // Add DND status - root["dnd"]["enabled"] = ledHandler.isDNDEnabled(); - root["dnd"]["timeBasedEnabled"] = ledHandler.isDNDTimeBasedEnabled(); - root["dnd"]["startTime"] = String(ledHandler.getDNDStartHour()) + ":" + - (ledHandler.getDNDStartMinute() < 10 ? "0" : "") + String(ledHandler.getDNDStartMinute()); - root["dnd"]["endTime"] = String(ledHandler.getDNDEndHour()) + ":" + - (ledHandler.getDNDEndMinute() < 10 ? "0" : "") + String(ledHandler.getDNDEndMinute()); - root["dnd"]["active"] = ledHandler.isDNDActive(); - return root; } -JsonDocument getLedStatusObject() -{ - auto& ledHandler = getLedHandler(); - auto& pixels = ledHandler.getPixels(); - +JsonDocument getLedStatusObject() { JsonDocument root; JsonArray colors = root["data"].to(); + // Adafruit_NeoPixel pix = getPixels(); - for (uint i = 0; i < pixels.numPixels(); i++) - { + for (uint i = 0; i < pixels.numPixels(); i++) { uint32_t pixColor = pixels.getPixelColor(pixels.numPixels() - i - 1); + uint alpha = (pixColor >> 24) & 0xFF; uint red = (pixColor >> 16) & 0xFF; uint green = (pixColor >> 8) & 0xFF; uint blue = pixColor & 0xFF; char hexColor[8]; - snprintf(hexColor, sizeof(hexColor), "#%02X%02X%02X", red, green, blue); - // colors.add(hexColor); + sprintf(hexColor, "#%02X%02X%02X", red, green, blue); JsonObject object = colors.add(); object["red"] = red; @@ -311,54 +142,45 @@ JsonDocument getLedStatusObject() } void eventSourceUpdate() { - if (!events.count()) return; - - static JsonDocument doc; - doc.clear(); - - JsonDocument root = getStatusObject(); - - root["leds"] = getLedStatusObject()["data"]; + if (!events.count()) return; + JsonDocument root = getStatusObject(); + JsonArray data = root["data"].to(); - // Get current EPD content directly as array - std::array epdContent = EPDManager::getInstance().getCurrentContent(); - - // Add EPD content arrays - JsonArray data = root["data"].to(); - - // Copy array elements directly - for(const auto& content : epdContent) { - data.add(content); - } + root["leds"] = getLedStatusObject()["data"]; - String buffer; - serializeJson(root, buffer); - events.send(buffer.c_str(), "status"); + String epdContent[NUM_SCREENS]; + std::array retEpdContent = getCurrentEpdContent(); + std::copy(std::begin(retEpdContent), std::end(retEpdContent), epdContent); + + copyArray(epdContent, data); + + String bufString; + serializeJson(root, bufString); + + events.send(bufString.c_str(), "status"); } /** * @Api * @Path("/api/status") */ -void onApiStatus(AsyncWebServerRequest *request) -{ +void onApiStatus(AsyncWebServerRequest *request) { AsyncResponseStream *response = - request->beginResponseStream(JSON_CONTENT); + request->beginResponseStream("application/json"); JsonDocument root = getStatusObject(); - - // Get current EPD content directly as array - std::array epdContent = EPDManager::getInstance().getCurrentContent(); - - // Add EPD content arrays JsonArray data = root["data"].to(); - - // Copy array elements directly - for(const auto& content : epdContent) { - data.add(content); - } + JsonArray rendered = root["rendered"].to(); + String epdContent[NUM_SCREENS]; root["leds"] = getLedStatusObject()["data"]; + + std::array retEpdContent = getCurrentEpdContent(); + + std::copy(std::begin(retEpdContent), std::end(retEpdContent), epdContent); + + copyArray(epdContent, data); + copyArray(epdContent, rendered); serializeJson(root, *response); request->send(response); @@ -368,231 +190,172 @@ void onApiStatus(AsyncWebServerRequest *request) * @Api * @Path("/api/action/pause") */ -void onApiActionPause(AsyncWebServerRequest *request) -{ +void onApiActionPause(AsyncWebServerRequest *request) { setTimerActive(false); - request->send(HTTP_OK); + request->send(200); }; /** * @Api * @Path("/api/action/timer_restart") */ -void onApiActionTimerRestart(AsyncWebServerRequest *request) -{ +void onApiActionTimerRestart(AsyncWebServerRequest *request) { setTimerActive(true); - request->send(HTTP_OK); + request->send(200); } /** * @Api * @Path("/api/full_refresh") */ -void onApiFullRefresh(AsyncWebServerRequest *request) -{ - EPDManager::getInstance().forceFullRefresh(); - std::array newEpdContent = EPDManager::getInstance().getCurrentContent(); - EPDManager::getInstance().setContent(newEpdContent, true); - request->send(HTTP_OK); +void onApiFullRefresh(AsyncWebServerRequest *request) { + forceFullRefresh(); + std::array newEpdContent = getCurrentEpdContent(); + + setEpdContent(newEpdContent, true); + + request->send(200); } /** * @Api * @Path("/api/show/screen") */ -void onApiShowScreen(AsyncWebServerRequest *request) -{ - if (request->hasParam("s")) - { - const AsyncWebParameter *p = request->getParam("s"); +void onApiShowScreen(AsyncWebServerRequest *request) { + if (request->hasParam("s")) { + AsyncWebParameter *p = request->getParam("s"); uint currentScreen = p->value().toInt(); - ScreenHandler::setCurrentScreen(currentScreen); + setCurrentScreen(currentScreen); } - request->send(HTTP_OK); + request->send(200); } -/** - * @Api - * @Path("/api/screen/next") - */ -void onApiScreenControl(AsyncWebServerRequest *request) { - const String& action = request->url(); - if (action.endsWith("/next")) { - ScreenHandler::nextScreen(); - } else if (action.endsWith("/previous")) { - ScreenHandler::previousScreen(); - } - request->send(HTTP_OK); -} - -void onApiShowText(AsyncWebServerRequest *request) -{ - if (request->hasParam("t")) - { - const AsyncWebParameter *p = request->getParam("t"); +void onApiShowText(AsyncWebServerRequest *request) { + if (request->hasParam("t")) { + AsyncWebParameter *p = request->getParam("t"); String t = p->value(); - t.toUpperCase(); // This is needed as long as lowercase letters are glitchy + t.toUpperCase(); // This is needed as long as lowercase letters are glitchy std::array textEpdContent; - for (uint i = 0; i < NUM_SCREENS; i++) - { + for (uint i = 0; i < NUM_SCREENS; i++) { textEpdContent[i] = t[i]; } - EPDManager::getInstance().setContent(textEpdContent); + setEpdContent(textEpdContent); } - ScreenHandler::setCurrentScreen(SCREEN_CUSTOM); - request->send(HTTP_OK); + setCurrentScreen(SCREEN_CUSTOM); + request->send(200); } -void onApiShowTextAdvanced(AsyncWebServerRequest *request, JsonVariant &json) -{ +void onApiShowTextAdvanced(AsyncWebServerRequest *request, JsonVariant &json) { JsonArray screens = json.as(); std::array epdContent; int i = 0; - for (JsonVariant s : screens) - { + for (JsonVariant s : screens) { epdContent[i] = s.as(); i++; } - EPDManager::getInstance().setContent(epdContent); + setEpdContent(epdContent); - ScreenHandler::setCurrentScreen(SCREEN_CUSTOM); - request->send(HTTP_OK); + setCurrentScreen(SCREEN_CUSTOM); + request->send(200); } -void onApiSettingsPatch(AsyncWebServerRequest *request, JsonVariant &json) -{ - if ( - preferences.getBool("httpAuthEnabled", DEFAULT_HTTP_AUTH_ENABLED) && - !request->authenticate( - preferences.getString("httpAuthUser", DEFAULT_HTTP_AUTH_USERNAME).c_str(), - preferences.getString("httpAuthPass", DEFAULT_HTTP_AUTH_PASSWORD).c_str())) - { - return request->requestAuthentication(); - } - +void onApiSettingsPatch(AsyncWebServerRequest *request, JsonVariant &json) { JsonObject settings = json.as(); bool settingsChanged = true; - if (settings["invertedColor"].is()) - { - bool inverted = settings["invertedColor"].as(); - preferences.putBool("invertedColor", inverted); - if (inverted) { - preferences.putUInt("fgColor", GxEPD_WHITE); - preferences.putUInt("bgColor", GxEPD_BLACK); - EPDManager::getInstance().setForegroundColor(GxEPD_WHITE); - EPDManager::getInstance().setBackgroundColor(GxEPD_BLACK); - } else { - preferences.putUInt("fgColor", GxEPD_BLACK); - preferences.putUInt("bgColor", GxEPD_WHITE); - EPDManager::getInstance().setForegroundColor(GxEPD_BLACK); - EPDManager::getInstance().setBackgroundColor(GxEPD_WHITE); - } - Serial.printf("Setting invertedColor to %d\r\n", inverted); + if (settings.containsKey("fgColor")) { + String fgColor = settings["fgColor"].as(); + preferences.putUInt("fgColor", strtol(fgColor.c_str(), NULL, 16)); + setFgColor(int(strtol(fgColor.c_str(), NULL, 16))); + Serial.print(F("Setting foreground color to ")); + Serial.println(strtol(fgColor.c_str(), NULL, 16)); + settingsChanged = true; + } + if (settings.containsKey("bgColor")) { + String bgColor = settings["bgColor"].as(); + + preferences.putUInt("bgColor", strtol(bgColor.c_str(), NULL, 16)); + setBgColor(int(strtol(bgColor.c_str(), NULL, 16))); + Serial.print(F("Setting background color to ")); + Serial.println(bgColor.c_str()); settingsChanged = true; } - if (settings["timePerScreen"].is()) - { + if (settings.containsKey("timePerScreen")) { preferences.putUInt("timerSeconds", settings["timePerScreen"].as() * 60); } - for (String setting : strSettings) - { - if (settings[setting].is()) - { + String strSettings[] = {"hostnamePrefix", "mempoolInstance"}; + + for (String setting : strSettings) { + if (settings.containsKey(setting)) { preferences.putString(setting.c_str(), settings[setting].as()); Serial.printf("Setting %s to %s\r\n", setting.c_str(), - settings[setting].as().c_str()); + settings[setting].as()); } } + String uintSettings[] = {"minSecPriceUpd", "fullRefreshMin", "ledBrightness"}; - - for (String setting : uintSettings) - { - if (settings[setting].is()) - { + for (String setting : uintSettings) { + if (settings.containsKey(setting)) { preferences.putUInt(setting.c_str(), settings[setting].as()); Serial.printf("Setting %s to %d\r\n", setting.c_str(), settings[setting].as()); } } - if (settings["tzOffset"].is()) - { + if (settings.containsKey("tzOffset")) { int gmtOffset = settings["tzOffset"].as() * 60; size_t written = preferences.putInt("gmtOffset", gmtOffset); Serial.printf("Setting %s to %d (%d minutes, written %d)\r\n", "gmtOffset", gmtOffset, settings["tzOffset"].as(), written); } - for (String setting : boolSettings) - { - if (settings[setting].is()) - { - preferences.putBool(setting.c_str(), settings[setting].as()); + String boolSettings[] = {"fetchEurPrice", "ledTestOnPower", "ledFlashOnUpd", + "mdnsEnabled", "otaEnabled", "stealFocus", + "mcapBigChar", "useSatsSymbol", "useBlkCountdown", + "suffixPrice", "disableLeds"}; + + for (String setting : boolSettings) { + if (settings.containsKey(setting)) { + preferences.putBool(setting.c_str(), settings[setting].as()); Serial.printf("Setting %s to %d\r\n", setting.c_str(), - settings[setting].as()); + settings[setting].as()); } } - if (settings["screens"].is()) - { - for (JsonVariant screen : settings["screens"].as()) - { + if (settings.containsKey("screens")) { + for (JsonVariant screen : settings["screens"].as()) { JsonObject s = screen.as(); uint id = s["id"].as(); String key = "screen[" + String(id) + "]"; String prefKey = "screen" + String(id) + "Visible"; - bool visible = s["enabled"].as(); + bool visible = s["enabled"].as(); preferences.putBool(prefKey.c_str(), visible); } } - if (settings["actCurrencies"].is()) - { - String actCurrencies; - - for (JsonVariant cur : settings["actCurrencies"].as()) - { - if (!actCurrencies.isEmpty()) - { - actCurrencies += ","; - } - actCurrencies += cur.as(); - } - - preferences.putString("actCurrencies", actCurrencies.c_str()); - Serial.printf("Set actCurrencies: %s\n", actCurrencies.c_str()); - } - - if (settings["txPower"].is()) - { + if (settings.containsKey("txPower")) { int txPower = settings["txPower"].as(); - if (txPower == 80) - { + if (txPower == 80) { preferences.remove("txPower"); - if (WiFi.getTxPower() != 80) - { + if (WiFi.getTxPower() != 80) { ESP.restart(); } - } - else if (static_cast(wifi_power_t::WIFI_POWER_MINUS_1dBm) <= - txPower && - txPower <= static_cast(wifi_power_t::WIFI_POWER_19_5dBm)) - { + } else if (static_cast(wifi_power_t::WIFI_POWER_MINUS_1dBm) <= + txPower && + txPower <= static_cast(wifi_power_t::WIFI_POWER_19_5dBm)) { // is valid value - if (WiFi.setTxPower(static_cast(txPower))) - { + if (WiFi.setTxPower(static_cast(txPower))) { Serial.printf("Set WiFi Tx power to: %d\n", txPower); preferences.putInt("txPower", txPower); settingsChanged = true; @@ -600,76 +363,20 @@ void onApiSettingsPatch(AsyncWebServerRequest *request, JsonVariant &json) } } - // Handle data source setting - if (settings["dataSource"].is()) { - uint8_t dataSource = settings["dataSource"].as(); - if (dataSource <= CUSTOM_SOURCE) { // Validate including custom source - preferences.putUChar("dataSource", dataSource); - Serial.printf("Setting dataSource to %d\r\n", dataSource); - settingsChanged = true; - } - } - - // Handle custom endpoint settings - if (settings["customEndpoint"].is()) { - preferences.putString("customEndpoint", settings["customEndpoint"].as()); - Serial.printf("Setting customEndpoint to %s\r\n", settings["customEndpoint"].as().c_str()); - settingsChanged = true; - } - - if (settings["customEndpointDisableSSL"].is()) { - preferences.putBool("customEndpointDisableSSL", settings["customEndpointDisableSSL"].as()); - Serial.printf("Setting customEndpointDisableSSL to %d\r\n", settings["customEndpointDisableSSL"].as()); - settingsChanged = true; - } - - // Handle DND settings - if (settings["dnd"].is()) { - JsonObject dndObj = settings["dnd"]; - auto& ledHandler = getLedHandler(); - - if (dndObj["timeBasedEnabled"].is()) { - ledHandler.setDNDTimeBasedEnabled(dndObj["timeBasedEnabled"].as()); - } - if (dndObj["startHour"].is() && dndObj["startMinute"].is() && - dndObj["endHour"].is() && dndObj["endMinute"].is()) { - ledHandler.setDNDTimeRange( - dndObj["startHour"].as(), - dndObj["startMinute"].as(), - dndObj["endHour"].as(), - dndObj["endMinute"].as()); - } - } - - request->send(HTTP_OK); - if (settingsChanged) - { - auto& ledHandler = getLedHandler(); - ledHandler.queueEffect(LED_FLASH_SUCCESS); + request->send(200); + if (settingsChanged) { + queueLedEffect(LED_FLASH_SUCCESS); } } -void onApiRestart(AsyncWebServerRequest *request) -{ - request->onDisconnect([]() { - delay(500); +void onApiRestart(AsyncWebServerRequest *request) { + request->send(200); - noInterrupts(); - esp_restart(); - }); + if (events.count()) events.send("closing"); - request->send(HTTP_OK); + delay(500); - if (events.count()) - events.send("closing"); -} - -void onApiIdentify(AsyncWebServerRequest *request) -{ - auto& ledHandler = getLedHandler(); - ledHandler.queueEffect(LED_FLASH_IDENTIFY); - - request->send(HTTP_OK); + esp_restart(); } /** @@ -677,174 +384,80 @@ void onApiIdentify(AsyncWebServerRequest *request) * @Method GET * @Path("/api/settings") */ -void onApiSettingsGet(AsyncWebServerRequest *request) -{ - if ( - preferences.getBool("httpAuthEnabled", DEFAULT_HTTP_AUTH_ENABLED) && - !request->authenticate( - preferences.getString("httpAuthUser", DEFAULT_HTTP_AUTH_USERNAME).c_str(), - preferences.getString("httpAuthPass", DEFAULT_HTTP_AUTH_PASSWORD).c_str())) - { - return request->requestAuthentication(); - } - +void onApiSettingsGet(AsyncWebServerRequest *request) { JsonDocument root; root["numScreens"] = NUM_SCREENS; - root["invertedColor"] = preferences.getBool("invertedColor", EPDManager::getInstance().getForegroundColor() == GxEPD_WHITE); + root["fgColor"] = getFgColor(); + root["bgColor"] = getBgColor(); root["timerSeconds"] = getTimerSeconds(); root["timerRunning"] = isTimerActive(); root["minSecPriceUpd"] = preferences.getUInt( "minSecPriceUpd", DEFAULT_SECONDS_BETWEEN_PRICE_UPDATE); root["fullRefreshMin"] = preferences.getUInt("fullRefreshMin", DEFAULT_MINUTES_FULL_REFRESH); - root["wpTimeout"] = preferences.getUInt("wpTimeout", DEFAULT_WP_TIMEOUT); - //root["tzOffset"] = preferences.getInt("gmtOffset", DEFAULT_TIME_OFFSET_SECONDS) / 60; - root["tzString"] = preferences.getString("tzString", DEFAULT_TZ_STRING); + root["wpTimeout"] = preferences.getUInt("wpTimeout", 600); + root["tzOffset"] = preferences.getInt("gmtOffset", TIME_OFFSET_SECONDS) / 60; + root["useBitcoinNode"] = preferences.getBool("useNode", false); + root["mempoolInstance"] = + preferences.getString("mempoolInstance", DEFAULT_MEMPOOL_INSTANCE); + root["ledTestOnPower"] = preferences.getBool("ledTestOnPower", true); + root["ledFlashOnUpd"] = preferences.getBool("ledFlashOnUpd", false); + root["ledBrightness"] = preferences.getUInt("ledBrightness", 128); + root["stealFocus"] = preferences.getBool("stealFocus", false); + root["mcapBigChar"] = preferences.getBool("mcapBigChar", true); + root["mdnsEnabled"] = preferences.getBool("mdnsEnabled", true); + root["otaEnabled"] = preferences.getBool("otaEnabled", true); + root["fetchEurPrice"] = preferences.getBool("fetchEurPrice", false); + root["useSatsSymbol"] = preferences.getBool("useSatsSymbol", false); + root["useBlkCountdown"] = preferences.getBool("useBlkCountdown", false); + root["suffixPrice"] = preferences.getBool("suffixPrice", false); + root["disableLeds"] = preferences.getBool("disableLeds", false); - // Add data source settings - root["dataSource"] = preferences.getUChar("dataSource", DEFAULT_DATA_SOURCE); - - // Mempool settings (only used for THIRD_PARTY_SOURCE) - root["mempoolInstance"] = preferences.getString("mempoolInstance", DEFAULT_MEMPOOL_INSTANCE); - root["mempoolSecure"] = preferences.getBool("mempoolSecure", DEFAULT_MEMPOOL_SECURE); - - // Local pool settings - root["localPoolEndpoint"] = preferences.getString("localPoolEndpoint", DEFAULT_LOCAL_POOL_ENDPOINT); - - // Nostr settings (used for NOSTR_SOURCE or when zapNotify is enabled) - root["nostrPubKey"] = preferences.getString("nostrPubKey", DEFAULT_NOSTR_NPUB); - root["nostrRelay"] = preferences.getString("nostrRelay", DEFAULT_NOSTR_RELAY); - root["nostrZapNotify"] = preferences.getBool("nostrZapNotify", DEFAULT_ZAP_NOTIFY_ENABLED); - root["nostrZapPubkey"] = preferences.getString("nostrZapPubkey", DEFAULT_ZAP_NOTIFY_PUBKEY); - root["ledFlashOnZap"] = preferences.getBool("ledFlashOnZap", DEFAULT_LED_FLASH_ON_ZAP); - root["scrnRestoreZap"] = preferences.getBool("scrnRestoreZap", DEFAULT_SCREEN_RESTORE_AFTER_ZAP); - root["fontName"] = preferences.getString("fontName", DEFAULT_FONT_NAME); - root["availableFonts"] = FontNames::getAvailableFonts(); - // Custom endpoint settings (only used for CUSTOM_SOURCE) - root["customEndpoint"] = preferences.getString("customEndpoint", DEFAULT_CUSTOM_ENDPOINT); - root["customEndpointDisableSSL"] = preferences.getBool("customEndpointDisableSSL", DEFAULT_CUSTOM_ENDPOINT_DISABLE_SSL); - - root["ledTestOnPower"] = preferences.getBool("ledTestOnPower", DEFAULT_LED_TEST_ON_POWER); - root["ledFlashOnUpd"] = preferences.getBool("ledFlashOnUpd", DEFAULT_LED_FLASH_ON_UPD); - root["ledBrightness"] = preferences.getUInt("ledBrightness", DEFAULT_LED_BRIGHTNESS); - root["stealFocus"] = preferences.getBool("stealFocus", DEFAULT_STEAL_FOCUS); - root["mcapBigChar"] = preferences.getBool("mcapBigChar", DEFAULT_MCAP_BIG_CHAR); - root["mdnsEnabled"] = preferences.getBool("mdnsEnabled", DEFAULT_MDNS_ENABLED); - root["otaEnabled"] = preferences.getBool("otaEnabled", DEFAULT_OTA_ENABLED); - root["useSatsSymbol"] = preferences.getBool("useSatsSymbol", DEFAULT_USE_SATS_SYMBOL); - root["useBlkCountdown"] = preferences.getBool("useBlkCountdown", DEFAULT_USE_BLOCK_COUNTDOWN); - root["suffixPrice"] = preferences.getBool("suffixPrice", DEFAULT_SUFFIX_PRICE); - root["disableLeds"] = preferences.getBool("disableLeds", DEFAULT_DISABLE_LEDS); - root["mowMode"] = preferences.getBool("mowMode", DEFAULT_MOW_MODE); - root["verticalDesc"] = preferences.getBool("verticalDesc", DEFAULT_VERTICAL_DESC); - - root["suffixShareDot"] = preferences.getBool("suffixShareDot", DEFAULT_SUFFIX_SHARE_DOT); - root["enableDebugLog"] = preferences.getBool("enableDebugLog", DEFAULT_ENABLE_DEBUG_LOG); - - root["hostnamePrefix"] = preferences.getString("hostnamePrefix", DEFAULT_HOSTNAME_PREFIX); + root["hostnamePrefix"] = preferences.getString("hostnamePrefix", "btclock"); root["hostname"] = getMyHostname(); root["ip"] = WiFi.localIP(); root["txPower"] = WiFi.getTxPower(); - root["gitReleaseUrl"] = preferences.getString("gitReleaseUrl", DEFAULT_GIT_RELEASE_URL); - - root["bitaxeEnabled"] = preferences.getBool("bitaxeEnabled", DEFAULT_BITAXE_ENABLED); - root["bitaxeHostname"] = preferences.getString("bitaxeHostname", DEFAULT_BITAXE_HOSTNAME); - - root["miningPoolStats"] = preferences.getBool("miningPoolStats", DEFAULT_MINING_POOL_STATS_ENABLED); - root["miningPoolName"] = preferences.getString("miningPoolName", DEFAULT_MINING_POOL_NAME); - root["miningPoolUser"] = preferences.getString("miningPoolUser", DEFAULT_MINING_POOL_USER); - root["availablePools"] = PoolFactory::getAvailablePools(); - root["httpAuthEnabled"] = preferences.getBool("httpAuthEnabled", DEFAULT_HTTP_AUTH_ENABLED); - root["httpAuthUser"] = preferences.getString("httpAuthUser", DEFAULT_HTTP_AUTH_USERNAME); - root["httpAuthPass"] = preferences.getString("httpAuthPass", DEFAULT_HTTP_AUTH_PASSWORD); -#ifdef HAS_FRONTLIGHT - root["hasFrontlight"] = true; - root["flDisable"] = preferences.getBool("flDisable"); - root["flMaxBrightness"] = preferences.getUInt("flMaxBrightness", DEFAULT_FL_MAX_BRIGHTNESS); - root["flAlwaysOn"] = preferences.getBool("flAlwaysOn", DEFAULT_FL_ALWAYS_ON); - root["flEffectDelay"] = preferences.getUInt("flEffectDelay", DEFAULT_FL_EFFECT_DELAY); - root["flFlashOnUpd"] = preferences.getBool("flFlashOnUpd", DEFAULT_FL_FLASH_ON_UPDATE); - root["flFlashOnZap"] = preferences.getBool("flFlashOnZap", DEFAULT_FL_FLASH_ON_ZAP); - - root["hasLightLevel"] = hasLightLevel(); - root["luxLightToggle"] = preferences.getUInt("luxLightToggle", DEFAULT_LUX_LIGHT_TOGGLE); - root["flOffWhenDark"] = preferences.getBool("flOffWhenDark", DEFAULT_FL_OFF_WHEN_DARK); - -#else - root["hasFrontlight"] = false; - root["hasLightLevel"] = false; -#endif - - root["hwRev"] = getHwRev(); - root["fsRev"] = getFsRev(); - #ifdef GIT_REV root["gitRev"] = String(GIT_REV); #endif -#ifdef GIT_TAG - root["gitTag"] = String(GIT_TAG); -#endif - #ifdef LAST_BUILD_TIME root["lastBuildTime"] = String(LAST_BUILD_TIME); #endif JsonArray screens = root["screens"].to(); - root["actCurrencies"] = getActiveCurrencies(); - root["availableCurrencies"] = getAvailableCurrencies(); + std::vector screenNameMap = getScreenNameMap(); - std::vector screenNameMap = getScreenNameMap(); - - for (int i = 0; i < screenNameMap.size(); i++) - { + for (int i = 0; i < screenNameMap.size(); i++) { JsonObject o = screens.add(); - String key = "screen" + String(screenNameMap.at(i).value) + "Visible"; - o["id"] = screenNameMap.at(i).value; - o["name"] = String(screenNameMap.at(i).name); + String key = "screen" + String(i) + "Visible"; + o["id"] = i; + o["name"] = screenNameMap[i]; o["enabled"] = preferences.getBool(key.c_str(), true); } - root["poolLogosUrl"] = preferences.getString("poolLogosUrl", DEFAULT_MINING_POOL_LOGOS_URL); - root["ceEndpoint"] = preferences.getString("ceEndpoint", DEFAULT_CUSTOM_ENDPOINT); - root["ceDisableSSL"] = preferences.getBool("ceDisableSSL", DEFAULT_CUSTOM_ENDPOINT_DISABLE_SSL); - - // Add DND settings - auto& ledHandler = getLedHandler(); - root["dnd"]["enabled"] = ledHandler.isDNDEnabled(); - root["dnd"]["timeBasedEnabled"] = ledHandler.isDNDTimeBasedEnabled(); - root["dnd"]["startHour"] = ledHandler.getDNDStartHour(); - root["dnd"]["startMinute"] = ledHandler.getDNDStartMinute(); - root["dnd"]["endHour"] = ledHandler.getDNDEndHour(); - root["dnd"]["endMinute"] = ledHandler.getDNDEndMinute(); - AsyncResponseStream *response = - request->beginResponseStream(JSON_CONTENT); + request->beginResponseStream("application/json"); serializeJson(root, *response); request->send(response); } -bool processEpdColorSettings(AsyncWebServerRequest *request) -{ +bool processEpdColorSettings(AsyncWebServerRequest *request) { bool settingsChanged = false; - if (request->hasParam("fgColor", true)) - { - const AsyncWebParameter *fgColor = request->getParam("fgColor", true); - uint32_t color = strtol(fgColor->value().c_str(), NULL, 16); - preferences.putUInt("fgColor", color); - EPDManager::getInstance().setForegroundColor(color); + if (request->hasParam("fgColor", true)) { + AsyncWebParameter *fgColor = request->getParam("fgColor", true); + preferences.putUInt("fgColor", strtol(fgColor->value().c_str(), NULL, 16)); + setFgColor(int(strtol(fgColor->value().c_str(), NULL, 16))); // Serial.print(F("Setting foreground color to ")); // Serial.println(fgColor->value().c_str()); settingsChanged = true; } - if (request->hasParam("bgColor", true)) - { - const AsyncWebParameter *bgColor = request->getParam("bgColor", true); + if (request->hasParam("bgColor", true)) { + AsyncWebParameter *bgColor = request->getParam("bgColor", true); - uint32_t color = strtol(bgColor->value().c_str(), NULL, 16); - preferences.putUInt("bgColor", color); - EPDManager::getInstance().setBackgroundColor(color); + preferences.putUInt("bgColor", strtol(bgColor->value().c_str(), NULL, 16)); + setBgColor(int(strtol(bgColor->value().c_str(), NULL, 16))); // Serial.print(F("Setting background color to ")); // Serial.println(bgColor->value().c_str()); settingsChanged = true; @@ -853,10 +466,192 @@ bool processEpdColorSettings(AsyncWebServerRequest *request) return settingsChanged; } -void onApiSystemStatus(AsyncWebServerRequest *request) -{ +void onApiSettingsPost(AsyncWebServerRequest *request) { + bool settingsChanged = false; + + settingsChanged = processEpdColorSettings(request); + + int headers = request->headers(); + int i; + for (i = 0; i < headers; i++) { + AsyncWebHeader *h = request->getHeader(i); + Serial.printf("HEADER[%s]: %s\n", h->name().c_str(), h->value().c_str()); + } + + int params = request->params(); + for (int i = 0; i < params; i++) { + AsyncWebParameter *p = request->getParam(i); + if (p->isFile()) { // p->isPost() is also true + Serial.printf("FILE[%s]: %s, size: %u\n", p->name().c_str(), + p->value().c_str(), p->size()); + } else if (p->isPost()) { + Serial.printf("POST[%s]: %s\n", p->name().c_str(), p->value().c_str()); + } else { + Serial.printf("GET[%s]: %s\n", p->name().c_str(), p->value().c_str()); + } + } + + if (request->hasParam("fetchEurPrice", true)) { + AsyncWebParameter *fetchEurPrice = request->getParam("fetchEurPrice", true); + + preferences.putBool("fetchEurPrice", fetchEurPrice->value().toInt()); + settingsChanged = true; + } else { + preferences.putBool("fetchEurPrice", 0); + settingsChanged = true; + } + + if (request->hasParam("ledTestOnPower", true)) { + AsyncWebParameter *ledTestOnPower = + request->getParam("ledTestOnPower", true); + + preferences.putBool("ledTestOnPower", ledTestOnPower->value().toInt()); + settingsChanged = true; + } else { + preferences.putBool("ledTestOnPower", 0); + settingsChanged = true; + } + + if (request->hasParam("ledFlashOnUpd", true)) { + AsyncWebParameter *ledFlashOnUpdate = + request->getParam("ledFlashOnUpd", true); + + preferences.putBool("ledFlashOnUpd", ledFlashOnUpdate->value().toInt()); + settingsChanged = true; + } else { + preferences.putBool("ledFlashOnUpd", 0); + settingsChanged = true; + } + + if (request->hasParam("mdnsEnabled", true)) { + AsyncWebParameter *mdnsEnabled = request->getParam("mdnsEnabled", true); + + preferences.putBool("mdnsEnabled", mdnsEnabled->value().toInt()); + settingsChanged = true; + } else { + preferences.putBool("mdnsEnabled", 0); + settingsChanged = true; + } + + if (request->hasParam("otaEnabled", true)) { + AsyncWebParameter *otaEnabled = request->getParam("otaEnabled", true); + + preferences.putBool("otaEnabled", otaEnabled->value().toInt()); + settingsChanged = true; + } else { + preferences.putBool("otaEnabled", 0); + settingsChanged = true; + } + + if (request->hasParam("stealFocusOnBlock", true)) { + AsyncWebParameter *stealFocusOnBlock = + request->getParam("stealFocusOnBlock", true); + + preferences.putBool("stealFocus", stealFocusOnBlock->value().toInt()); + settingsChanged = true; + } else { + preferences.putBool("stealFocus", 0); + settingsChanged = true; + } + + if (request->hasParam("mcapBigChar", true)) { + AsyncWebParameter *mcapBigChar = request->getParam("mcapBigChar", true); + + preferences.putBool("mcapBigChar", mcapBigChar->value().toInt()); + settingsChanged = true; + } else { + preferences.putBool("mcapBigChar", 0); + settingsChanged = true; + } + + if (request->hasParam("mempoolInstance", true)) { + AsyncWebParameter *mempoolInstance = + request->getParam("mempoolInstance", true); + + preferences.putString("mempoolInstance", mempoolInstance->value().c_str()); + settingsChanged = true; + } + + if (request->hasParam("hostnamePrefix", true)) { + AsyncWebParameter *hostnamePrefix = + request->getParam("hostnamePrefix", true); + + preferences.putString("hostnamePrefix", hostnamePrefix->value().c_str()); + settingsChanged = true; + } + + if (request->hasParam("ledBrightness", true)) { + AsyncWebParameter *ledBrightness = request->getParam("ledBrightness", true); + + preferences.putUInt("ledBrightness", ledBrightness->value().toInt()); + settingsChanged = true; + } + + if (request->hasParam("fullRefreshMin", true)) { + AsyncWebParameter *fullRefreshMin = + request->getParam("fullRefreshMin", true); + + preferences.putUInt("fullRefreshMin", fullRefreshMin->value().toInt()); + settingsChanged = true; + } + + if (request->hasParam("wpTimeout", true)) { + AsyncWebParameter *wpTimeout = request->getParam("wpTimeout", true); + + preferences.putUInt("wpTimeout", wpTimeout->value().toInt()); + settingsChanged = true; + } + + std::vector screenNameMap = getScreenNameMap(); + + if (request->hasParam("screens")) { + AsyncWebParameter *screenParam = request->getParam("screens", true); + + Serial.printf(screenParam->value().c_str()); + } + + for (int i = 0; i < screenNameMap.size(); i++) { + String key = "screen[" + String(i) + "]"; + String prefKey = "screen" + String(i) + "Visible"; + bool visible = false; + if (request->hasParam(key, true)) { + AsyncWebParameter *screenParam = request->getParam(key, true); + visible = screenParam->value().toInt(); + } + + preferences.putBool(prefKey.c_str(), visible); + } + + if (request->hasParam("tzOffset", true)) { + AsyncWebParameter *p = request->getParam("tzOffset", true); + int tzOffsetSeconds = p->value().toInt() * 60; + preferences.putInt("gmtOffset", tzOffsetSeconds); + settingsChanged = true; + } + + if (request->hasParam("minSecPriceUpd", true)) { + AsyncWebParameter *p = request->getParam("minSecPriceUpd", true); + int minSecPriceUpd = p->value().toInt(); + preferences.putUInt("minSecPriceUpd", minSecPriceUpd); + settingsChanged = true; + } + + if (request->hasParam("timePerScreen", true)) { + AsyncWebParameter *p = request->getParam("timePerScreen", true); + uint timerSeconds = p->value().toInt() * 60; + preferences.putUInt("timerSeconds", timerSeconds); + settingsChanged = true; + } + + request->send(200); + if (settingsChanged) { + queueLedEffect(LED_FLASH_SUCCESS); + } +} + +void onApiSystemStatus(AsyncWebServerRequest *request) { AsyncResponseStream *response = - request->beginResponseStream(JSON_CONTENT); + request->beginResponseStream("application/json"); JsonDocument root; @@ -864,9 +659,6 @@ void onApiSystemStatus(AsyncWebServerRequest *request) root["espHeapSize"] = ESP.getHeapSize(); root["espFreePsram"] = ESP.getFreePsram(); root["espPsramSize"] = ESP.getPsramSize(); - root["fsUsedBytes"] = LittleFS.usedBytes(); - root["fsTotalBytes"] = LittleFS.totalBytes(); - root["rssi"] = WiFi.RSSI(); root["txPower"] = WiFi.getTxPower(); @@ -878,15 +670,12 @@ void onApiSystemStatus(AsyncWebServerRequest *request) #define STRINGIFY(x) #x #define ENUM_TO_STRING(x) STRINGIFY(x) -void onApiSetWifiTxPower(AsyncWebServerRequest *request) -{ - if (request->hasParam("txPower")) - { - const AsyncWebParameter *txPowerParam = request->getParam("txPower"); +void onApiSetWifiTxPower(AsyncWebServerRequest *request) { + if (request->hasParam("txPower")) { + AsyncWebParameter *txPowerParam = request->getParam("txPower"); int txPower = txPowerParam->value().toInt(); if (static_cast(wifi_power_t::WIFI_POWER_MINUS_1dBm) <= txPower && - txPower <= static_cast(wifi_power_t::WIFI_POWER_19_5dBm)) - { + txPower <= static_cast(wifi_power_t::WIFI_POWER_19_5dBm)) { // is valid value String txPowerName = std::to_string( @@ -895,77 +684,66 @@ void onApiSetWifiTxPower(AsyncWebServerRequest *request) Serial.printf("Set WiFi Tx power to: %s\n", txPowerName); - if (WiFi.setTxPower(static_cast(txPower))) - { + if (WiFi.setTxPower(static_cast(txPower))) { preferences.putInt("txPower", txPower); - request->send(HTTP_OK, "application/json", "{\"setTxPower\": \"ok\"}"); + request->send(200, "application/json", "{\"setTxPower\": \"ok\"}"); return; } } } - return request->send(HTTP_BAD_REQUEST); + return request->send(400); } -void onApiLightsStatus(AsyncWebServerRequest *request) -{ +void onApiLightsStatus(AsyncWebServerRequest *request) { AsyncResponseStream *response = - request->beginResponseStream(JSON_CONTENT); + request->beginResponseStream("application/json"); serializeJson(getLedStatusObject()["data"], *response); request->send(response); } -void onApiStopDataSources(AsyncWebServerRequest *request) -{ +void onApiStopDataSources(AsyncWebServerRequest *request) { AsyncResponseStream *response = - request->beginResponseStream(JSON_CONTENT); + request->beginResponseStream("application/json"); stopPriceNotify(); - BlockNotify::getInstance().stop(); + stopBlockNotify(); request->send(response); } -void onApiRestartDataSources(AsyncWebServerRequest *request) -{ +void onApiRestartDataSources(AsyncWebServerRequest *request) { AsyncResponseStream *response = - request->beginResponseStream(JSON_CONTENT); + request->beginResponseStream("application/json"); - restartPriceNotify(); - BlockNotify::getInstance().restart(); + stopPriceNotify(); + stopBlockNotify(); + setupPriceNotify(); + setupBlockNotify(); request->send(response); } -void onApiLightsOff(AsyncWebServerRequest *request) -{ - auto& ledHandler = getLedHandler(); - ledHandler.setLights(0, 0, 0); - request->send(HTTP_OK); +void onApiLightsOff(AsyncWebServerRequest *request) { + setLights(0, 0, 0); + request->send(200); } -void onApiLightsSetColor(AsyncWebServerRequest *request) -{ - if (request->hasParam("c")) - { +void onApiLightsSetColor(AsyncWebServerRequest *request) { + if (request->hasParam("c")) { AsyncResponseStream *response = - request->beginResponseStream(JSON_CONTENT); + request->beginResponseStream("application/json"); String rgbColor = request->getParam("c")->value(); - if (rgbColor.compareTo("off") == 0) - { - auto& ledHandler = getLedHandler(); - ledHandler.setLights(0, 0, 0); - } - else - { + if (rgbColor.compareTo("off") == 0) { + setLights(0, 0, 0); + } else { uint r, g, b; sscanf(rgbColor.c_str(), "%02x%02x%02x", &r, &g, &b); - auto& ledHandler = getLedHandler(); - ledHandler.setLights(r, g, b); + setLights(r, g, b); } JsonDocument doc; @@ -974,58 +752,38 @@ void onApiLightsSetColor(AsyncWebServerRequest *request) serializeJson(getLedStatusObject()["data"], *response); request->send(response); - } - else - { - request->send(HTTP_BAD_REQUEST); + } else { + request->send(400); } } -void onApiLightsSetJson(AsyncWebServerRequest *request, JsonVariant &json) -{ - auto& ledHandler = getLedHandler(); - auto& pixels = ledHandler.getPixels(); - +void onApiLightsSetJson(AsyncWebServerRequest *request, JsonVariant &json) { JsonArray lights = json.as(); - if (lights.size() != pixels.numPixels()) - { - if (!lights.size()) - { - // if empty, assume off request - return onApiLightsOff(request); - } - + if (lights.size() != pixels.numPixels()) { Serial.printf("Invalid values for LED set %d\n", lights.size()); - request->send(HTTP_BAD_REQUEST); + request->send(400); return; } - for (uint i = 0; i < pixels.numPixels(); i++) - { + for (uint i = 0; i < pixels.numPixels(); i++) { unsigned int red, green, blue; - if (lights[i]["red"].is() && lights[i]["green"].is() && - lights[i]["blue"].is()) - { + if (lights[i].containsKey("red") && lights[i].containsKey("green") && + lights[i].containsKey("blue")) { red = lights[i]["red"].as(); green = lights[i]["green"].as(); blue = lights[i]["blue"].as(); - } - else if (lights[i]["hex"].is()) - { + } else if (lights[i].containsKey("hex")) { if (!sscanf(lights[i]["hex"].as().c_str(), "#%02X%02X%02X", &red, - &green, &blue) == 3) - { + &green, &blue) == 3) { Serial.printf("Invalid hex for LED %d\n", i); - request->send(HTTP_BAD_REQUEST); + request->send(400); return; } - } - else - { + } else { Serial.printf("No valid color for LED %d\n", i); - request->send(HTTP_BAD_REQUEST); + request->send(400); return; } @@ -1034,236 +792,66 @@ void onApiLightsSetJson(AsyncWebServerRequest *request, JsonVariant &json) } pixels.show(); - ledHandler.saveLedState(); + saveLedState(); - request->send(HTTP_OK); + request->send(200); } -void onIndex(AsyncWebServerRequest *request) -{ +void onIndex(AsyncWebServerRequest *request) { request->send(LittleFS, "/index.html", String(), false); } -void onNotFound(AsyncWebServerRequest *request) -{ - // Access-Control-Request-Method == POST might be better +void onNotFound(AsyncWebServerRequest *request) { + // Serial.printf("NotFound, URL[%s]\n", request->url()); + + // Serial.printf("NotFound, METHOD[%s]\n", request->methodToString()); + + // int headers = request->headers(); + // int i; + // for (i = 0; i < headers; i++) + // { + // AsyncWebHeader *h = request->getHeader(i); + // Serial.printf("NotFound HEADER[%s]: %s\n", h->name().c_str(), + // h->value().c_str()); + // } + + // int params = request->params(); + // for (int i = 0; i < params; i++) + // { + // AsyncWebParameter *p = request->getParam(i); + // if (p->isFile()) + // { // p->isPost() is also true + // Serial.printf("NotFound FILE[%s]: %s, size: %u\n", + // p->name().c_str(), p->value().c_str(), p->size()); + // } + // else if (p->isPost()) + // { + // Serial.printf("NotFound POST[%s]: %s\n", p->name().c_str(), + // p->value().c_str()); + // } + // else + // { + // Serial.printf("NotFound GET[%s]: %s\n", p->name().c_str(), + // p->value().c_str()); + // } + // } + + // Access-Control-Request-Method == POST might be better if (request->method() == HTTP_OPTIONS || - request->hasHeader("Sec-Fetch-Mode")) - { + request->hasHeader("Sec-Fetch-Mode")) { // Serial.printf("NotFound, Return[%d]\n", 200); - request->send(HTTP_OK); - } - else - { + request->send(200); + } else { // Serial.printf("NotFound, Return[%d]\n", 404); request->send(404); } }; -void eventSourceTask(void *pvParameters) -{ - for (;;) - { +void eventSourceTask(void *pvParameters) { + for (;;) { ulTaskNotifyTake(pdTRUE, portMAX_DELAY); eventSourceUpdate(); } -} - -void onApiShowCurrency(AsyncWebServerRequest *request) -{ - if (request->hasParam("c")) - { - const AsyncWebParameter *p = request->getParam("c"); - std::string currency = p->value().c_str(); - - if (!isActiveCurrency(currency)) - { - request->send(404); - return; - } - - char curChar = getCurrencyChar(currency); - - ScreenHandler::setCurrentCurrency(curChar); - ScreenHandler::setCurrentScreen(ScreenHandler::getCurrentScreen()); - - request->send(HTTP_OK); - return; - } - request->send(404); -} - -#ifdef HAS_FRONTLIGHT -void onApiFrontlightOn(AsyncWebServerRequest *request) -{ - auto& ledHandler = getLedHandler(); - ledHandler.frontlightFadeInAll(); - - request->send(HTTP_OK); -} - -void onApiFrontlightStatus(AsyncWebServerRequest *request) -{ - auto& ledHandler = getLedHandler(); - AsyncResponseStream *response = - request->beginResponseStream(JSON_CONTENT); - - JsonDocument root; - - std::vector statuses = ledHandler.frontlightGetStatus(); - uint16_t arr[NUM_SCREENS]; - std::copy(statuses.begin(), statuses.end(), arr); - - JsonArray data = root["flStatus"].to(); - copyArray(arr, data); - serializeJson(root, *response); - - request->send(response); -} - -void onApiFrontlightFlash(AsyncWebServerRequest *request) -{ - auto& ledHandler = getLedHandler(); - ledHandler.frontlightFlash(preferences.getUInt("flEffectDelay")); - - request->send(HTTP_OK); -} - -void onApiFrontlightSetBrightness(AsyncWebServerRequest *request) -{ - if (request->hasParam("b")) - { - auto& ledHandler = getLedHandler(); - ledHandler.frontlightSetBrightness(request->getParam("b")->value().toInt()); - request->send(HTTP_OK); - } - else - { - request->send(HTTP_BAD_REQUEST); - } -} - -void onApiFrontlightOff(AsyncWebServerRequest *request) -{ - auto& ledHandler = getLedHandler(); - ledHandler.frontlightFadeOutAll(); - - request->send(HTTP_OK); -} -#endif - -void onApiDNDTimeBasedEnable(AsyncWebServerRequest *request) { - auto& ledHandler = getLedHandler(); - ledHandler.setDNDTimeBasedEnabled(true); - request->send(200); -} - -void onApiDNDTimeBasedDisable(AsyncWebServerRequest *request) { - auto& ledHandler = getLedHandler(); - ledHandler.setDNDTimeBasedEnabled(false); - request->send(200); -} - -void onApiDNDSetTimeRange(AsyncWebServerRequest *request) { - if (request->hasParam("startHour") && request->hasParam("startMinute") && - request->hasParam("endHour") && request->hasParam("endMinute")) { - auto& ledHandler = getLedHandler(); - uint8_t startHour = request->getParam("startHour")->value().toInt(); - uint8_t startMinute = request->getParam("startMinute")->value().toInt(); - uint8_t endHour = request->getParam("endHour")->value().toInt(); - uint8_t endMinute = request->getParam("endMinute")->value().toInt(); - - ledHandler.setDNDTimeRange(startHour, startMinute, endHour, endMinute); - request->send(200); - } else { - request->send(400); - } -} - -void onApiDNDStatus(AsyncWebServerRequest *request) { - auto& ledHandler = getLedHandler(); - JsonDocument doc; - doc["enabled"] = ledHandler.isDNDEnabled(); - doc["timeBasedEnabled"] = ledHandler.isDNDTimeBasedEnabled(); - doc["startTime"] = String(ledHandler.getDNDStartHour()) + ":" + - (ledHandler.getDNDStartMinute() < 10 ? "0" : "") + String(ledHandler.getDNDStartMinute()); - doc["endTime"] = String(ledHandler.getDNDEndHour()) + ":" + - (ledHandler.getDNDEndMinute() < 10 ? "0" : "") + String(ledHandler.getDNDEndMinute()); - doc["active"] = ledHandler.isDNDActive(); - - String response; - serializeJson(doc, response); - request->send(200, "application/json", response); -} - -void onApiDNDEnable(AsyncWebServerRequest *request) { - auto& ledHandler = getLedHandler(); - ledHandler.setDNDEnabled(true); - request->send(200); -} - -void onApiDNDDisable(AsyncWebServerRequest *request) { - auto& ledHandler = getLedHandler(); - ledHandler.setDNDEnabled(false); - request->send(200); -} - -void onApiLightsGet(AsyncWebServerRequest *request) -{ - auto& ledHandler = getLedHandler(); - auto& pixels = ledHandler.getPixels(); - - JsonDocument doc; - JsonArray lights = doc.createNestedArray("lights"); - - for (uint i = 0; i < pixels.numPixels(); i++) - { - uint32_t pixColor = pixels.getPixelColor(pixels.numPixels() - i - 1); - JsonObject light = lights.createNestedObject(); - light["r"] = (uint8_t)(pixColor >> 16); - light["g"] = (uint8_t)(pixColor >> 8); - light["b"] = (uint8_t)pixColor; - } - - String output; - serializeJson(doc, output); - request->send(200, "application/json", output); -} - -void onApiLightsPost(AsyncWebServerRequest *request, uint8_t *data, size_t len, - size_t index, size_t total) -{ - auto& ledHandler = getLedHandler(); - auto& pixels = ledHandler.getPixels(); - - JsonDocument doc; - DeserializationError error = deserializeJson(doc, data); - if (error) - { - request->send(400); - return; - } - - JsonArray lights = doc["lights"]; - if (lights.size() != pixels.numPixels()) - { - request->send(400); - return; - } - - for (uint i = 0; i < pixels.numPixels(); i++) - { - JsonObject light = lights[i]; - uint8_t red = light["r"]; - uint8_t green = light["g"]; - uint8_t blue = light["b"]; - - pixels.setPixelColor((pixels.numPixels() - i - 1), - pixels.Color(red, green, blue)); - } - pixels.show(); - - request->send(200); } \ No newline at end of file diff --git a/src/lib/webserver.hpp b/src/lib/webserver.hpp index ddd6b73..c910c3e 100644 --- a/src/lib/webserver.hpp +++ b/src/lib/webserver.hpp @@ -14,7 +14,6 @@ #include "lib/price_notify.hpp" #include "lib/screen_handler.hpp" #include "webserver/OneParamRewrite.hpp" -#include "lib/mining_pool/pool_factory.hpp" extern TaskHandle_t eventSourceTaskHandle; @@ -22,25 +21,18 @@ void stopWebServer(); void setupWebserver(); bool processEpdColorSettings(AsyncWebServerRequest *request); - - void onApiStatus(AsyncWebServerRequest *request); void onApiSystemStatus(AsyncWebServerRequest *request); void onApiSetWifiTxPower(AsyncWebServerRequest *request); -void onApiScreenControl(AsyncWebServerRequest *request); - void onApiShowScreen(AsyncWebServerRequest *request); -void onApiShowCurrency(AsyncWebServerRequest *request); - void onApiShowText(AsyncWebServerRequest *request); -void onApiIdentify(AsyncWebServerRequest *request); - void onApiShowTextAdvanced(AsyncWebServerRequest *request, JsonVariant &json); void onApiActionPause(AsyncWebServerRequest *request); void onApiActionTimerRestart(AsyncWebServerRequest *request); void onApiSettingsGet(AsyncWebServerRequest *request); +void onApiSettingsPost(AsyncWebServerRequest *request); void onApiSettingsPatch(AsyncWebServerRequest *request, JsonVariant &json); void onApiFullRefresh(AsyncWebServerRequest *request); @@ -50,11 +42,6 @@ void onApiLightsSetColor(AsyncWebServerRequest *request); void onApiLightsSetJson(AsyncWebServerRequest *request, JsonVariant &json); void onApiRestart(AsyncWebServerRequest *request); -void onFirmwareUpdate(AsyncWebServerRequest *request); -void asyncFirmwareUpdateHandler(AsyncWebServerRequest *request, String filename, size_t index, uint8_t *data, size_t len, bool final); -void asyncFileUpdateHandler(AsyncWebServerRequest *request, String filename, size_t index, uint8_t *data, size_t len, bool final, int command); -void asyncWebuiUpdateHandler(AsyncWebServerRequest *request, String filename, size_t index, uint8_t *data, size_t len, bool final); -void onAutoUpdateFirmware(AsyncWebServerRequest *request); void onIndex(AsyncWebServerRequest *request); void onNotFound(AsyncWebServerRequest *request); @@ -65,17 +52,4 @@ void eventSourceUpdate(); void eventSourceTask(void *pvParameters); void onApiStopDataSources(AsyncWebServerRequest *request); -void onApiRestartDataSources(AsyncWebServerRequest *request); - -void onApiDNDStatus(AsyncWebServerRequest *request); -void onApiDNDEnable(AsyncWebServerRequest *request); -void onApiDNDDisable(AsyncWebServerRequest *request); - -#ifdef HAS_FRONTLIGHT -void onApiFrontlightOn(AsyncWebServerRequest *request); -void onApiFrontlightFlash(AsyncWebServerRequest *request); -void onApiFrontlightSetBrightness(AsyncWebServerRequest *request); - -void onApiFrontlightStatus(AsyncWebServerRequest *request); -void onApiFrontlightOff(AsyncWebServerRequest *request); -#endif \ No newline at end of file +void onApiRestartDataSources(AsyncWebServerRequest *request); \ No newline at end of file diff --git a/src/main.cpp b/src/main.cpp index 08d38ad..47e73fb 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,5 +1,5 @@ /* - * Copyright 2023-2024 Djuri Baars + * Copyright 2023 Djuri Baars * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,146 +18,81 @@ #define WEBSERVER_H #include "ESPAsyncWebServer.h" #include "lib/config.hpp" -#include "lib/led_handler.hpp" -#include "lib/block_notify.hpp" uint wifiLostConnection; uint priceNotifyLostConnection = 0; uint blockNotifyLostConnection = 0; -int64_t getUptime() { - return esp_timer_get_time() / 1000000; -} - -void handlePriceNotifyDisconnection() { - if (priceNotifyLostConnection == 0) { - priceNotifyLostConnection = getUptime(); - Serial.println(F("Lost price notification connection, trying to reconnect...")); - } - - if ((getUptime() - priceNotifyLostConnection) > 300) { // 5 minutes timeout - Serial.println(F("Price notification connection lost for 5 minutes, restarting handler...")); - restartPriceNotify(); - priceNotifyLostConnection = 0; - } -} - -void handleBlockNotifyDisconnection() { - if (blockNotifyLostConnection == 0) { - blockNotifyLostConnection = getUptime(); - Serial.println(F("Lost block notification connection, trying to reconnect...")); - } - - if ((getUptime() - blockNotifyLostConnection) > 300) { // 5 minutes timeout - Serial.println(F("Block notification connection lost for 5 minutes, restarting handler...")); - auto& blockNotify = BlockNotify::getInstance(); - blockNotify.restart(); - blockNotifyLostConnection = 0; - } -} - -void handleFrontlight() { -#ifdef HAS_FRONTLIGHT - if (hasLightLevel() && preferences.getUInt("luxLightToggle", DEFAULT_LUX_LIGHT_TOGGLE) != 0) { - uint lightLevel = getLightLevel(); - uint luxThreshold = preferences.getUInt("luxLightToggle", DEFAULT_LUX_LIGHT_TOGGLE); - auto& ledHandler = getLedHandler(); - - if (lightLevel <= 1 && preferences.getBool("flOffWhenDark", DEFAULT_FL_OFF_WHEN_DARK)) { - if (ledHandler.frontlightIsOn()) ledHandler.frontlightFadeOutAll(); - } else if (lightLevel < luxThreshold && !ledHandler.frontlightIsOn()) { - ledHandler.frontlightFadeInAll(); - } else if (ledHandler.frontlightIsOn() && lightLevel > luxThreshold) { - ledHandler.frontlightFadeOutAll(); - } - } -#endif -} - -void checkWiFiConnection() { - if (!WiFi.isConnected()) { - if (!wifiLostConnection) { - wifiLostConnection = getUptime(); - Serial.println(F("Lost WiFi connection, trying to reconnect...")); - } - if ((getUptime() - wifiLostConnection) > 600) { - Serial.println(F("Still no connection after 10 minutes, restarting...")); - delay(2000); - ESP.restart(); - } - WiFi.begin(); - } else if (wifiLostConnection) { - wifiLostConnection = 0; - Serial.println(F("Connection restored, reset timer.")); - } -} - -void checkMissedBlocks() { - Serial.println(F("Long time (45 min) since last block, checking if I missed anything...")); - auto& blockNotify = BlockNotify::getInstance(); - int currentBlock = blockNotify.fetchLatestBlock(); - if (currentBlock != -1) { - if (currentBlock != blockNotify.getBlockHeight()) { - Serial.println(F("Detected stuck block height... restarting block handler.")); - blockNotify.restart(); - } - blockNotify.setLastBlockUpdate(getUptime()); - } -} - -void monitorDataConnections() { - // Price notification monitoring - if (getPriceNotifyInit() && !preferences.getBool("fetchEurPrice", DEFAULT_FETCH_EUR_PRICE) && !isPriceNotifyConnected()) { - handlePriceNotifyDisconnection(); - } else if (priceNotifyLostConnection > 0 && isPriceNotifyConnected()) { - priceNotifyLostConnection = 0; - } - - // Block notification monitoring - auto& blockNotify = BlockNotify::getInstance(); - if (blockNotify.isInitialized() && !blockNotify.isConnected()) { - handleBlockNotifyDisconnection(); - } else if (blockNotifyLostConnection > 0 && blockNotify.isConnected()) { - blockNotifyLostConnection = 0; - } - - // Check for missed price updates - if ((getLastPriceUpdate(CURRENCY_USD) - getUptime()) > (preferences.getUInt("minSecPriceUpd", DEFAULT_SECONDS_BETWEEN_PRICE_UPDATE) * 5)) { - Serial.println(F("Detected 5 missed price updates... restarting price handler.")); - restartPriceNotify(); - priceNotifyLostConnection = 0; - } - - // Check for missed blocks - if ((blockNotify.getLastBlockUpdate() - getUptime()) > 45 * 60) { - checkMissedBlocks(); - } -} - extern "C" void app_main() { initArduino(); + Serial.begin(115200); setup(); - bool thirdPartySource = getDataSource() == THIRD_PARTY_SOURCE; - while (true) { - if (eventSourceTaskHandle != NULL) { + // vTaskList(ptrTaskList); + // Serial.println(F("**********************************")); + // Serial.println(F("Task State Prio Stack Num")); + // Serial.println(F("**********************************")); + // Serial.print(ptrTaskList); + // Serial.println(F("**********************************")); + if (eventSourceTaskHandle != NULL) xTaskNotifyGive(eventSourceTaskHandle); + + int64_t currentUptime = esp_timer_get_time() / 1000000;; + + if (!WiFi.isConnected()) { + if (!wifiLostConnection) { + wifiLostConnection = currentUptime; + Serial.println("Lost WiFi connection, trying to reconnect..."); + } + + if ((currentUptime - wifiLostConnection) > 600) { + Serial.println("Still no connection after 10 minutes, restarting..."); + delay(2000); + ESP.restart(); + } + + WiFi.begin(); + } else if (wifiLostConnection) { + wifiLostConnection = 0; + Serial.println("Connection restored, reset timer."); + } else if (getPriceNotifyInit() && !preferences.getBool("fetchEurPrice", false) && !isPriceNotifyConnected()) { + priceNotifyLostConnection++; + Serial.println("Lost price data connection..."); + queueLedEffect(LED_DATA_PRICE_ERROR); + + // if price WS connection does not come back after 6*5 seconds, destroy and recreate + if (priceNotifyLostConnection > 6) { + Serial.println("Restarting price handler..."); + + stopPriceNotify(); + setupPriceNotify(); + priceNotifyLostConnection = 0; + } + } else if (getBlockNotifyInit() && !isBlockNotifyConnected()) { + blockNotifyLostConnection++; + Serial.println("Lost block data connection..."); + queueLedEffect(LED_DATA_BLOCK_ERROR); + // if mempool WS connection does not come back after 6*5 seconds, destroy and recreate + if (blockNotifyLostConnection > 6) { + Serial.println("Restarting block handler..."); + + stopBlockNotify(); + setupBlockNotify(); + blockNotifyLostConnection = 0; + } + } else if (blockNotifyLostConnection > 0 || priceNotifyLostConnection > 0) { + blockNotifyLostConnection = 0; + priceNotifyLostConnection = 0; } - if (!getIsOTAUpdating()) { - handleFrontlight(); - checkWiFiConnection(); + // if more than 5 price updates are missed, there is probably something wrong, reconnect + if ((getLastPriceUpdate() - currentUptime) > (preferences.getUInt("minSecPriceUpd", DEFAULT_SECONDS_BETWEEN_PRICE_UPDATE)*5)) { + stopPriceNotify(); + setupPriceNotify(); - if (thirdPartySource) { - monitorDataConnections(); - } - - if (getUptime() - getLastTimeSync() > 24 * 60 * 60) { - Serial.println(F("Last time update is longer than 24 hours ago, sync again")); - syncTime(); - } + priceNotifyLostConnection = 0; } vTaskDelay(pdMS_TO_TICKS(5000)); diff --git a/test/test_bitaxehandler/test_main.cpp b/test/test_bitaxehandler/test_main.cpp deleted file mode 100644 index 4336107..0000000 --- a/test/test_bitaxehandler/test_main.cpp +++ /dev/null @@ -1,75 +0,0 @@ -#include -#include - -template -std::string joinArrayWithBrackets(const std::array& arr, const std::string& separator = " ") { - std::ostringstream result; - for (size_t i = 0; i < N; ++i) { - if (i > 0) { - result << separator; - } - result << '[' << arr[i] << ']'; - } - return result.str(); -} - -void setUp(void) -{ - // set stuff up here -} - -void tearDown(void) -{ - // clean stuff up here -} - -void test_BitaxeParseHashrate(void) -{ - std::array output = parseBitaxeHashRate(656130000000); - - std::string joined = joinArrayWithBrackets(output); - - - TEST_ASSERT_EQUAL_STRING_MESSAGE("mdi:bitaxe", output[0].c_str(), joined.c_str()); - - TEST_ASSERT_EQUAL_STRING_MESSAGE("6", output[NUM_SCREENS - 4].c_str(), joined.c_str()); - TEST_ASSERT_EQUAL_STRING_MESSAGE("5", output[NUM_SCREENS - 3].c_str(), joined.c_str()); - TEST_ASSERT_EQUAL_STRING_MESSAGE("6", output[NUM_SCREENS - 2].c_str(), joined.c_str()); - TEST_ASSERT_EQUAL_STRING_MESSAGE("GH/S", output[NUM_SCREENS - 1].c_str(), joined.c_str()); -} - -void test_BitaxeParseBestDiff(void) -{ - std::array output = parseBitaxeBestDiff(15800000000); - - std::string joined = joinArrayWithBrackets(output); - - TEST_ASSERT_EQUAL_STRING_MESSAGE("mdi:bitaxe", output[0].c_str(), joined.c_str()); - - - TEST_ASSERT_EQUAL_STRING_MESSAGE("1", output[NUM_SCREENS - 5].c_str(), joined.c_str()); - TEST_ASSERT_EQUAL_STRING_MESSAGE("5", output[NUM_SCREENS - 4].c_str(), joined.c_str()); - TEST_ASSERT_EQUAL_STRING_MESSAGE(".", output[NUM_SCREENS - 3].c_str(), joined.c_str()); - TEST_ASSERT_EQUAL_STRING_MESSAGE("8", output[NUM_SCREENS - 2].c_str(), joined.c_str()); - TEST_ASSERT_EQUAL_STRING_MESSAGE("G", output[NUM_SCREENS - 1].c_str(), joined.c_str()); -} - -// not needed when using generate_test_runner.rb -int runUnityTests(void) -{ - UNITY_BEGIN(); - RUN_TEST(test_BitaxeParseHashrate); - RUN_TEST(test_BitaxeParseBestDiff); - - return UNITY_END(); -} - -int main(void) -{ - return runUnityTests(); -} - -extern "C" void app_main() -{ - runUnityTests(); -} diff --git a/test/test_datahandler/test_main.cpp b/test/test_datahandler/test_main.cpp index 24118e4..2c9ffb2 100644 --- a/test/test_datahandler/test_main.cpp +++ b/test/test_datahandler/test_main.cpp @@ -1,310 +1,118 @@ #include #include -template -std::string joinArrayWithBrackets(const std::array& arr, const std::string& separator = " ") { - std::ostringstream result; - for (size_t i = 0; i < N; ++i) { - if (i > 0) { - result << separator; - } - result << '[' << arr[i] << ']'; - } - return result.str(); -} - -void setUp(void) -{ +void setUp(void) { // set stuff up here } -void tearDown(void) -{ +void tearDown(void) { // clean stuff up here } -void test_CorrectSatsPerDollarConversion(void) -{ - std::array output = parseSatsPerCurrency(37253, CURRENCY_USD, false); +void test_CorrectSatsPerDollarConversion(void) { + std::array output = parseSatsPerCurrency(37253, '$', false); TEST_ASSERT_EQUAL_STRING("MSCW/TIME", output[0].c_str()); - TEST_ASSERT_EQUAL_STRING("2", output[NUM_SCREENS - 4].c_str()); - TEST_ASSERT_EQUAL_STRING("6", output[NUM_SCREENS - 3].c_str()); - TEST_ASSERT_EQUAL_STRING("8", output[NUM_SCREENS - 2].c_str()); - TEST_ASSERT_EQUAL_STRING("4", output[NUM_SCREENS - 1].c_str()); + TEST_ASSERT_EQUAL_STRING("2", output[NUM_SCREENS-4].c_str()); + TEST_ASSERT_EQUAL_STRING("6", output[NUM_SCREENS-3].c_str()); + TEST_ASSERT_EQUAL_STRING("8", output[NUM_SCREENS-2].c_str()); + TEST_ASSERT_EQUAL_STRING("4", output[NUM_SCREENS-1].c_str()); } -void test_SatsPerDollarAfter1B(void) -{ - std::array output = parseSatsPerCurrency(120000000, CURRENCY_USD, false); - TEST_ASSERT_EQUAL_STRING("SATS/USD", output[0].c_str()); - TEST_ASSERT_EQUAL_STRING("0", output[NUM_SCREENS - 5].c_str()); - TEST_ASSERT_EQUAL_STRING(".", output[NUM_SCREENS - 4].c_str()); - TEST_ASSERT_EQUAL_STRING("8", output[NUM_SCREENS - 3].c_str()); - TEST_ASSERT_EQUAL_STRING("3", output[NUM_SCREENS - 2].c_str()); - TEST_ASSERT_EQUAL_STRING("3", output[NUM_SCREENS - 1].c_str()); -} -void test_CorrectSatsPerPoundConversion(void) -{ - std::array output = parseSatsPerCurrency(37253, CURRENCY_GBP, false); - TEST_ASSERT_EQUAL_STRING("SATS/GBP", output[0].c_str()); - TEST_ASSERT_EQUAL_STRING("2", output[NUM_SCREENS - 4].c_str()); - TEST_ASSERT_EQUAL_STRING("6", output[NUM_SCREENS - 3].c_str()); - TEST_ASSERT_EQUAL_STRING("8", output[NUM_SCREENS - 2].c_str()); - TEST_ASSERT_EQUAL_STRING("4", output[NUM_SCREENS - 1].c_str()); -} - -void test_SixCharacterBlockHeight(void) -{ +void test_SixCharacterBlockHeight(void) { std::array output = parseBlockHeight(999999); TEST_ASSERT_EQUAL_STRING("BLOCK/HEIGHT", output[0].c_str()); TEST_ASSERT_EQUAL_STRING("9", output[1].c_str()); } -void test_SevenCharacterBlockHeight(void) -{ +void test_SevenCharacterBlockHeight(void) { std::array output = parseBlockHeight(1000000); TEST_ASSERT_EQUAL_STRING("1", output[0].c_str()); TEST_ASSERT_EQUAL_STRING("0", output[1].c_str()); } -void test_FeeRateDisplay(void) -{ +void test_FeeRateDisplay(void) { uint testValue = 21; std::array output = parseBlockFees(static_cast(testValue)); TEST_ASSERT_EQUAL_STRING("FEE/RATE", output[0].c_str()); - TEST_ASSERT_EQUAL_STRING("2", output[NUM_SCREENS - 3].c_str()); - TEST_ASSERT_EQUAL_STRING("1", output[NUM_SCREENS - 2].c_str()); - TEST_ASSERT_EQUAL_STRING("sat/vB", output[NUM_SCREENS - 1].c_str()); + TEST_ASSERT_EQUAL_STRING("2", output[NUM_SCREENS-3].c_str()); + TEST_ASSERT_EQUAL_STRING("1", output[NUM_SCREENS-2].c_str()); + TEST_ASSERT_EQUAL_STRING("sat/vB", output[NUM_SCREENS-1].c_str()); } -void test_PriceOf100kusd(void) -{ + +void test_PriceOf100kusd(void) { std::array output = parsePriceData(100000, '$'); TEST_ASSERT_EQUAL_STRING("$", output[0].c_str()); TEST_ASSERT_EQUAL_STRING("1", output[1].c_str()); } -void test_PriceOf1MillionUsd(void) -{ +void test_PriceOf1MillionUsd(void) { std::array output = parsePriceData(1000000, '$'); TEST_ASSERT_EQUAL_STRING("BTC/USD", output[0].c_str()); - - TEST_ASSERT_EQUAL_STRING("1", output[NUM_SCREENS - 5].c_str()); - TEST_ASSERT_EQUAL_STRING(".", output[NUM_SCREENS - 4].c_str()); - TEST_ASSERT_EQUAL_STRING("0", output[NUM_SCREENS - 3].c_str()); - TEST_ASSERT_EQUAL_STRING("0", output[NUM_SCREENS - 2].c_str()); - TEST_ASSERT_EQUAL_STRING("M", output[NUM_SCREENS - 1].c_str()); + + TEST_ASSERT_EQUAL_STRING("1", output[NUM_SCREENS-5].c_str()); + TEST_ASSERT_EQUAL_STRING(".", output[NUM_SCREENS-4].c_str()); + TEST_ASSERT_EQUAL_STRING("0", output[NUM_SCREENS-3].c_str()); + TEST_ASSERT_EQUAL_STRING("0", output[NUM_SCREENS-2].c_str()); + TEST_ASSERT_EQUAL_STRING("M", output[NUM_SCREENS-1].c_str()); } -void test_PriceSuffixMode(void) -{ - std::array output = parsePriceData(93000, '$', true, false); - TEST_ASSERT_EQUAL_STRING("BTC/USD", output[0].c_str()); - - TEST_ASSERT_EQUAL_STRING("9", output[NUM_SCREENS - 5].c_str()); - TEST_ASSERT_EQUAL_STRING("3", output[NUM_SCREENS - 4].c_str()); - TEST_ASSERT_EQUAL_STRING(".", output[NUM_SCREENS - 3].c_str()); - TEST_ASSERT_EQUAL_STRING("0", output[NUM_SCREENS - 2].c_str()); - TEST_ASSERT_EQUAL_STRING("K", output[NUM_SCREENS - 1].c_str()); -} - -void test_PriceSuffixModeCompact1(void) -{ - std::array output = parsePriceData(100000, '$', true, false, true); - - std::string joined = joinArrayWithBrackets(output); - - TEST_ASSERT_EQUAL_STRING_MESSAGE("BTC/USD", output[0].c_str(), joined.c_str()); - - TEST_ASSERT_EQUAL_STRING_MESSAGE("$", output[NUM_SCREENS - 6].c_str(), joined.c_str()); - TEST_ASSERT_EQUAL_STRING_MESSAGE("1", output[NUM_SCREENS - 5].c_str(), joined.c_str()); - TEST_ASSERT_EQUAL_STRING_MESSAGE("0", output[NUM_SCREENS - 4].c_str(), joined.c_str()); - TEST_ASSERT_EQUAL_STRING_MESSAGE("0.", output[NUM_SCREENS - 3].c_str(), joined.c_str()); - TEST_ASSERT_EQUAL_STRING_MESSAGE("0", output[NUM_SCREENS - 2].c_str(), joined.c_str()); - TEST_ASSERT_EQUAL_STRING_MESSAGE("K", output[NUM_SCREENS - 1].c_str(), joined.c_str()); -} - -void test_PriceSuffixModeCompact2(void) -{ - std::array output = parsePriceData(1000000, '$', true, false, true); - - std::string joined = joinArrayWithBrackets(output); - - TEST_ASSERT_EQUAL_STRING_MESSAGE("BTC/USD", output[0].c_str(), joined.c_str()); - - TEST_ASSERT_EQUAL_STRING_MESSAGE("$", output[NUM_SCREENS - 6].c_str(), joined.c_str()); - TEST_ASSERT_EQUAL_STRING_MESSAGE("1.", output[NUM_SCREENS - 5].c_str(), joined.c_str()); - TEST_ASSERT_EQUAL_STRING_MESSAGE("0", output[NUM_SCREENS - 4].c_str(), joined.c_str()); - TEST_ASSERT_EQUAL_STRING_MESSAGE("0", output[NUM_SCREENS - 3].c_str(), joined.c_str()); - TEST_ASSERT_EQUAL_STRING_MESSAGE("0", output[NUM_SCREENS - 2].c_str(), joined.c_str()); - TEST_ASSERT_EQUAL_STRING_MESSAGE("M", output[NUM_SCREENS - 1].c_str(), joined.c_str()); -} - -void test_PriceSuffixModeMow(void) -{ - std::array output = parsePriceData(93600, '$', true, true); - - std::string joined = joinArrayWithBrackets(output); - - TEST_ASSERT_EQUAL_STRING_MESSAGE("$", output[0].c_str(), joined.c_str()); - - TEST_ASSERT_EQUAL_STRING_MESSAGE(".", output[NUM_SCREENS - 5].c_str(), joined.c_str()); - TEST_ASSERT_EQUAL_STRING_MESSAGE("0", output[NUM_SCREENS - 4].c_str(), joined.c_str()); - TEST_ASSERT_EQUAL_STRING_MESSAGE("9", output[NUM_SCREENS - 3].c_str(), joined.c_str()); - TEST_ASSERT_EQUAL_STRING_MESSAGE("3", output[NUM_SCREENS - 2].c_str(), joined.c_str()); - TEST_ASSERT_EQUAL_STRING_MESSAGE("M", output[NUM_SCREENS - 1].c_str(), joined.c_str()); -} - -void test_PriceSuffixModeMowCompact(void) -{ - std::array output = parsePriceData(93600, '$', true, true, true); - - std::string joined = joinArrayWithBrackets(output); - - TEST_ASSERT_EQUAL_STRING_MESSAGE("MOW/UNITS", output[0].c_str(), joined.c_str()); - - TEST_ASSERT_EQUAL_STRING_MESSAGE("$", output[NUM_SCREENS - 6].c_str(), joined.c_str()); - TEST_ASSERT_EQUAL_STRING_MESSAGE("0.", output[NUM_SCREENS - 5].c_str(), joined.c_str()); - TEST_ASSERT_EQUAL_STRING_MESSAGE("0", output[NUM_SCREENS - 4].c_str(), joined.c_str()); - TEST_ASSERT_EQUAL_STRING_MESSAGE("9", output[NUM_SCREENS - 3].c_str(), joined.c_str()); - TEST_ASSERT_EQUAL_STRING_MESSAGE("3", output[NUM_SCREENS - 2].c_str(), joined.c_str()); - TEST_ASSERT_EQUAL_STRING_MESSAGE("M", output[NUM_SCREENS - 1].c_str(), joined.c_str()); -} - -void test_McapLowerUsd(void) -{ +void test_McapLowerUsd(void) { std::array output = parseMarketCap(810000, 26000, '$', true); TEST_ASSERT_EQUAL_STRING("USD/MCAP", output[0].c_str()); - // TEST_ASSERT_EQUAL_STRING("$", output[NUM_SCREENS-6].c_str()); - TEST_ASSERT_EQUAL_STRING("$", output[NUM_SCREENS - 5].c_str()); - TEST_ASSERT_EQUAL_STRING("5", output[NUM_SCREENS - 4].c_str()); - TEST_ASSERT_EQUAL_STRING("0", output[NUM_SCREENS - 3].c_str()); - TEST_ASSERT_EQUAL_STRING("7", output[NUM_SCREENS - 2].c_str()); - TEST_ASSERT_EQUAL_STRING("B", output[NUM_SCREENS - 1].c_str()); +// TEST_ASSERT_EQUAL_STRING("$", output[NUM_SCREENS-6].c_str()); + TEST_ASSERT_EQUAL_STRING("$", output[NUM_SCREENS-5].c_str()); + TEST_ASSERT_EQUAL_STRING("5", output[NUM_SCREENS-4].c_str()); + TEST_ASSERT_EQUAL_STRING("0", output[NUM_SCREENS-3].c_str()); + TEST_ASSERT_EQUAL_STRING("7", output[NUM_SCREENS-2].c_str()); + TEST_ASSERT_EQUAL_STRING("B", output[NUM_SCREENS-1].c_str()); } -void test_Mcap1TrillionUsd(void) -{ +void test_Mcap1TrillionUsd(void) { std::array output = parseMarketCap(831000, 52000, '$', true); TEST_ASSERT_EQUAL_STRING("USD/MCAP", output[0].c_str()); - TEST_ASSERT_EQUAL_STRING("$", output[NUM_SCREENS - 6].c_str()); - TEST_ASSERT_EQUAL_STRING("1", output[NUM_SCREENS - 5].c_str()); - TEST_ASSERT_EQUAL_STRING(".", output[NUM_SCREENS - 4].c_str()); - TEST_ASSERT_EQUAL_STRING("0", output[NUM_SCREENS - 3].c_str()); - TEST_ASSERT_EQUAL_STRING("2", output[NUM_SCREENS - 2].c_str()); - TEST_ASSERT_EQUAL_STRING("T", output[NUM_SCREENS - 1].c_str()); + TEST_ASSERT_EQUAL_STRING("$", output[NUM_SCREENS-6].c_str()); + TEST_ASSERT_EQUAL_STRING("1", output[NUM_SCREENS-5].c_str()); + TEST_ASSERT_EQUAL_STRING(".", output[NUM_SCREENS-4].c_str()); + TEST_ASSERT_EQUAL_STRING("0", output[NUM_SCREENS-3].c_str()); + TEST_ASSERT_EQUAL_STRING("2", output[NUM_SCREENS-2].c_str()); + TEST_ASSERT_EQUAL_STRING("T", output[NUM_SCREENS-1].c_str()); } -void test_Mcap1TrillionUsdSmallChars(void) -{ - std::array output = parseMarketCap(831000, 52000, '$', false); - TEST_ASSERT_EQUAL_STRING("USD/MCAP", output[0].c_str()); - - std::string joined = joinArrayWithBrackets(output); - - - - TEST_ASSERT_EQUAL_STRING_MESSAGE(" $ ", output[NUM_SCREENS - 6].c_str(), joined.c_str()); - - TEST_ASSERT_EQUAL_STRING_MESSAGE(" 1", output[NUM_SCREENS - 5].c_str(), joined.c_str()); - TEST_ASSERT_EQUAL_STRING_MESSAGE("020", output[NUM_SCREENS - 4].c_str(), joined.c_str()); - TEST_ASSERT_EQUAL_STRING_MESSAGE("825", output[NUM_SCREENS - 3].c_str(), joined.c_str()); - TEST_ASSERT_EQUAL_STRING_MESSAGE("000", output[NUM_SCREENS - 2].c_str(), joined.c_str()); - TEST_ASSERT_EQUAL_STRING_MESSAGE("000", output[NUM_SCREENS - 1].c_str(), joined.c_str()); -} - -void test_Mcap1TrillionEur(void) -{ - std::array output = parseMarketCap(831000, 52000, CURRENCY_EUR, true); +void test_Mcap1TrillionEur(void) { + std::array output = parseMarketCap(831000, 52000, '[', true); TEST_ASSERT_EQUAL_STRING("EUR/MCAP", output[0].c_str()); - TEST_ASSERT_TRUE(CURRENCY_EUR == output[NUM_SCREENS - 6].c_str()[0]); - TEST_ASSERT_EQUAL_STRING("1", output[NUM_SCREENS - 5].c_str()); - TEST_ASSERT_EQUAL_STRING(".", output[NUM_SCREENS - 4].c_str()); - TEST_ASSERT_EQUAL_STRING("0", output[NUM_SCREENS - 3].c_str()); - TEST_ASSERT_EQUAL_STRING("2", output[NUM_SCREENS - 2].c_str()); - TEST_ASSERT_EQUAL_STRING("T", output[NUM_SCREENS - 1].c_str()); -} - -void test_Mcap1TrillionEurSmallChars(void) -{ - std::array output = parseMarketCap(831000, 52000, CURRENCY_EUR, false); - TEST_ASSERT_EQUAL_STRING("EUR/MCAP", output[0].c_str()); - - std::string joined = joinArrayWithBrackets(output); - - char result[4]; - snprintf(result, sizeof(result), " %c ", CURRENCY_EUR); - TEST_ASSERT_EQUAL_STRING(result, output[NUM_SCREENS - 6].c_str()); - TEST_ASSERT_EQUAL_STRING_MESSAGE(" 1", output[NUM_SCREENS - 5].c_str(), joined.c_str()); - TEST_ASSERT_EQUAL_STRING_MESSAGE("020", output[NUM_SCREENS - 4].c_str(), joined.c_str()); - TEST_ASSERT_EQUAL_STRING_MESSAGE("825", output[NUM_SCREENS - 3].c_str(), joined.c_str()); - TEST_ASSERT_EQUAL_STRING_MESSAGE("000", output[NUM_SCREENS - 2].c_str(), joined.c_str()); - TEST_ASSERT_EQUAL_STRING_MESSAGE("000", output[NUM_SCREENS - 1].c_str(), joined.c_str()); -} - -void test_Mcap1TrillionJpy(void) -{ - std::array output = parseMarketCap(831000, 52000, CURRENCY_JPY, true); - TEST_ASSERT_EQUAL_STRING("JPY/MCAP", output[0].c_str()); - TEST_ASSERT_TRUE(CURRENCY_JPY == output[NUM_SCREENS - 6].c_str()[0]); - TEST_ASSERT_EQUAL_STRING("1", output[NUM_SCREENS - 5].c_str()); - TEST_ASSERT_EQUAL_STRING(".", output[NUM_SCREENS - 4].c_str()); - TEST_ASSERT_EQUAL_STRING("0", output[NUM_SCREENS - 3].c_str()); - TEST_ASSERT_EQUAL_STRING("2", output[NUM_SCREENS - 2].c_str()); - TEST_ASSERT_EQUAL_STRING("T", output[NUM_SCREENS - 1].c_str()); -} - -void test_Mcap1TrillionJpySmallChars(void) -{ - std::array output = parseMarketCap(831000, 52000, CURRENCY_JPY, false); - TEST_ASSERT_EQUAL_STRING("JPY/MCAP", output[0].c_str()); - - char result[4]; - snprintf(result, sizeof(result), " %c ", CURRENCY_JPY); - TEST_ASSERT_EQUAL_STRING(result, output[NUM_SCREENS - 6].c_str()); - TEST_ASSERT_EQUAL_STRING(" 1", output[NUM_SCREENS - 5].c_str()); - TEST_ASSERT_EQUAL_STRING("020", output[NUM_SCREENS - 4].c_str()); - TEST_ASSERT_EQUAL_STRING("825", output[NUM_SCREENS - 3].c_str()); - TEST_ASSERT_EQUAL_STRING("000", output[NUM_SCREENS - 2].c_str()); - TEST_ASSERT_EQUAL_STRING("000", output[NUM_SCREENS - 1].c_str()); + TEST_ASSERT_EQUAL_STRING("[", output[NUM_SCREENS-6].c_str()); + TEST_ASSERT_EQUAL_STRING("1", output[NUM_SCREENS-5].c_str()); + TEST_ASSERT_EQUAL_STRING(".", output[NUM_SCREENS-4].c_str()); + TEST_ASSERT_EQUAL_STRING("0", output[NUM_SCREENS-3].c_str()); + TEST_ASSERT_EQUAL_STRING("2", output[NUM_SCREENS-2].c_str()); + TEST_ASSERT_EQUAL_STRING("T", output[NUM_SCREENS-1].c_str()); } // not needed when using generate_test_runner.rb -int runUnityTests(void) -{ +int runUnityTests(void) { UNITY_BEGIN(); RUN_TEST(test_CorrectSatsPerDollarConversion); - RUN_TEST(test_CorrectSatsPerPoundConversion); - RUN_TEST(test_SatsPerDollarAfter1B); RUN_TEST(test_SixCharacterBlockHeight); RUN_TEST(test_SevenCharacterBlockHeight); RUN_TEST(test_FeeRateDisplay); RUN_TEST(test_PriceOf100kusd); RUN_TEST(test_McapLowerUsd); RUN_TEST(test_Mcap1TrillionUsd); - RUN_TEST(test_Mcap1TrillionUsdSmallChars); RUN_TEST(test_Mcap1TrillionEur); - RUN_TEST(test_Mcap1TrillionEurSmallChars); - RUN_TEST(test_Mcap1TrillionJpy); - RUN_TEST(test_Mcap1TrillionJpySmallChars); - RUN_TEST(test_PriceSuffixMode); - RUN_TEST(test_PriceSuffixModeCompact1); - RUN_TEST(test_PriceSuffixModeCompact2); - RUN_TEST(test_PriceSuffixModeMow); - RUN_TEST(test_PriceSuffixModeMowCompact); + //RUN_TEST(test_Mcap1MillionEur); return UNITY_END(); } -int main(void) -{ - return runUnityTests(); +int main(void) { + return runUnityTests(); } -extern "C" void app_main() -{ - runUnityTests(); +extern "C" void app_main() { + runUnityTests(); } diff --git a/test/test_mining_pool/test_main.cpp b/test/test_mining_pool/test_main.cpp deleted file mode 100644 index f028aba..0000000 --- a/test/test_mining_pool/test_main.cpp +++ /dev/null @@ -1,75 +0,0 @@ -#include -#include - -void test_parseMiningPoolStatsHashRate1dot34TH(void) -{ - std::string hashrate; - std::string label; - std::string output; - - parseHashrateString("1340000000000", label, output, 4); - - TEST_ASSERT_EQUAL_STRING_MESSAGE("TH/S", label.c_str(), label.c_str()); - TEST_ASSERT_EQUAL_STRING_MESSAGE("1.34", output.c_str(), output.c_str()); -} - -void test_parseMiningPoolStatsHashRate645GH(void) -{ - std::string hashrate = "645000000000"; - std::string label; - std::string output; - - parseHashrateString(hashrate, label, output, 4); - - TEST_ASSERT_EQUAL_STRING_MESSAGE("GH/S", label.c_str(), label.c_str()); - TEST_ASSERT_EQUAL_STRING_MESSAGE("645", output.c_str(), output.c_str()); -} - -void test_parseMiningPoolStatsHashRateEmpty(void) -{ - std::string hashrate = ""; - std::string label; - std::string output; - - parseHashrateString(hashrate, label, output, 4); - - TEST_ASSERT_EQUAL_STRING_MESSAGE("H/S", label.c_str(), label.c_str()); - TEST_ASSERT_EQUAL_STRING_MESSAGE("0", output.c_str(), output.c_str()); -} - -void test_parseMiningPoolStatsHashRateZero(void) -{ - std::string hashrate = "0"; - std::string label; - std::string output; - - parseHashrateString(hashrate, label, output, 4); - - TEST_ASSERT_EQUAL_STRING_MESSAGE("H/S", label.c_str(), label.c_str()); - TEST_ASSERT_EQUAL_STRING_MESSAGE("0", output.c_str(), output.c_str()); -} - - - - -// not needed when using generate_test_runner.rb -int runUnityTests(void) -{ - UNITY_BEGIN(); - RUN_TEST(test_parseMiningPoolStatsHashRate1dot34TH); - RUN_TEST(test_parseMiningPoolStatsHashRate645GH); - RUN_TEST(test_parseMiningPoolStatsHashRateZero); - RUN_TEST(test_parseMiningPoolStatsHashRateEmpty); - - return UNITY_END(); -} - -int main(void) -{ - return runUnityTests(); -} - -extern "C" void app_main() -{ - runUnityTests(); -} diff --git a/x509_crt_bundle b/x509_crt_bundle deleted file mode 100644 index 77d8ea3..0000000 Binary files a/x509_crt_bundle and /dev/null differ