diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile
index 62f0b7ead..d599f447f 100644
--- a/.devcontainer/Dockerfile
+++ b/.devcontainer/Dockerfile
@@ -1,9 +1,10 @@
+# trunk-ignore-all(terrascan/AC_DOCKER_0002): Known terrascan issue
+# trunk-ignore-all(hadolint/DL3008): Do not pin apt package versions
+# trunk-ignore-all(hadolint/DL3013): Do not pin pip package versions
FROM mcr.microsoft.com/devcontainers/cpp:1-debian-12
USER root
-# trunk-ignore(terrascan/AC_DOCKER_0002): Known terrascan issue
-# trunk-ignore(hadolint/DL3008): Use latest version of packages
RUN apt-get update && export DEBIAN_FRONTEND=noninteractive \
&& apt-get -y install --no-install-recommends \
ca-certificates \
@@ -27,9 +28,11 @@ RUN apt-get update && export DEBIAN_FRONTEND=noninteractive \
hwdata \
gpg \
gnupg2 \
+ libusb-1.0-0-dev \
+ libi2c-dev \
&& apt-get clean && rm -rf /var/lib/apt/lists/*
-RUN pipx install platformio==6.1.15
+RUN pipx install platformio
COPY 99-platformio-udev.rules /etc/udev/rules.d/99-platformio-udev.rules
diff --git a/.github/ISSUE_TEMPLATE/Bug Report.yml b/.github/ISSUE_TEMPLATE/Bug Report.yml
index f2d2f6507..f638b9018 100644
--- a/.github/ISSUE_TEMPLATE/Bug Report.yml
+++ b/.github/ISSUE_TEMPLATE/Bug Report.yml
@@ -1,7 +1,7 @@
name: Bug Report
description: File a bug report
title: "[Bug]: "
-labels: ["bug", "triage"]
+labels: [bug, triage]
body:
- type: markdown
attributes:
diff --git a/.github/ISSUE_TEMPLATE/New Board.yml b/.github/ISSUE_TEMPLATE/New Board.yml
index c71ed4ba2..90b2a9bf9 100644
--- a/.github/ISSUE_TEMPLATE/New Board.yml
+++ b/.github/ISSUE_TEMPLATE/New Board.yml
@@ -1,7 +1,7 @@
name: New Board
description: Request us to support new hardware
title: "[Board]: "
-labels: ["enhancement", "triage"]
+labels: [enhancement, triage]
body:
- type: markdown
attributes:
diff --git a/.github/ISSUE_TEMPLATE/feature.yml b/.github/ISSUE_TEMPLATE/feature.yml
index b50ccac26..311f097c4 100644
--- a/.github/ISSUE_TEMPLATE/feature.yml
+++ b/.github/ISSUE_TEMPLATE/feature.yml
@@ -1,7 +1,7 @@
name: Feature Request
description: Request a new feature
title: "[Feature Request]: "
-labels: ["enhancement"]
+labels: [enhancement]
body:
- type: markdown
attributes:
diff --git a/.github/actionlint.yaml b/.github/actionlint.yaml
new file mode 100644
index 000000000..f7bf95f83
--- /dev/null
+++ b/.github/actionlint.yaml
@@ -0,0 +1,5 @@
+# Configuration related to self-hosted runner.
+self-hosted-runner:
+ # Labels of self-hosted runner in array of strings.
+ labels:
+ - test-runner
diff --git a/.github/actions/build-variant/action.yml b/.github/actions/build-variant/action.yml
index b24a5fc12..2f0883fad 100644
--- a/.github/actions/build-variant/action.yml
+++ b/.github/actions/build-variant/action.yml
@@ -34,7 +34,7 @@ inputs:
arch:
description: Processor arch name
required: true
- default: "esp32"
+ default: esp32
runs:
using: composite
diff --git a/.github/actions/setup-base/action.yml b/.github/actions/setup-base/action.yml
index 7364c4ddb..7cd0dfcac 100644
--- a/.github/actions/setup-base/action.yml
+++ b/.github/actions/setup-base/action.yml
@@ -1,13 +1,13 @@
-name: "Setup Build Base Composite Action"
-description: "Base build actions for Meshtastic Platform IO steps"
+name: Setup Build Base Composite Action
+description: Base build actions for Meshtastic Platform IO steps
runs:
- using: "composite"
+ using: composite
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
- submodules: "recursive"
+ submodules: recursive
ref: ${{github.event.pull_request.head.ref}}
repository: ${{github.event.pull_request.head.repo.full_name}}
diff --git a/.github/dependabot.yml b/.github/dependabot.yml
index 616c16ce2..a7b4a0f1b 100644
--- a/.github/dependabot.yml
+++ b/.github/dependabot.yml
@@ -1,26 +1,27 @@
+#trunk-ignore-all(yamllint/quoted-strings): required by dependabot syntax check
version: 2
updates:
- package-ecosystem: docker
- directory: devcontainer
+ directory: /.devcontainer
schedule:
interval: daily
- time: "05:00" # trunk-ignore(yamllint/quoted-strings): required by dependabot syntax check
+ time: "05:00"
timezone: US/Pacific
- package-ecosystem: docker
directory: /
schedule:
interval: daily
- time: "05:00" # trunk-ignore(yamllint/quoted-strings): required by dependabot syntax check
+ time: "05:00"
timezone: US/Pacific
- package-ecosystem: gitsubmodule
directory: /
schedule:
interval: daily
- time: "05:00" # trunk-ignore(yamllint/quoted-strings): required by dependabot syntax check
+ time: "05:00"
timezone: US/Pacific
- package-ecosystem: github-actions
directory: /.github/workflows
schedule:
interval: daily
- time: "05:00" # trunk-ignore(yamllint/quoted-strings): required by dependabot syntax check
+ time: "05:00"
timezone: US/Pacific
diff --git a/.github/workflows/build_nrf52.yml b/.github/workflows/build_nrf52.yml
index ce26838f2..786508f86 100644
--- a/.github/workflows/build_nrf52.yml
+++ b/.github/workflows/build_nrf52.yml
@@ -7,6 +7,8 @@ on:
required: true
type: string
+permissions: read-all
+
jobs:
build-nrf52:
runs-on: ubuntu-latest
diff --git a/.github/workflows/build_rpi2040.yml b/.github/workflows/build_rpi2040.yml
index 492a1f010..53fee34d2 100644
--- a/.github/workflows/build_rpi2040.yml
+++ b/.github/workflows/build_rpi2040.yml
@@ -7,6 +7,8 @@ on:
required: true
type: string
+permissions: read-all
+
jobs:
build-rpi2040:
runs-on: ubuntu-latest
diff --git a/.github/workflows/build_stm32.yml b/.github/workflows/build_stm32.yml
index b463bab71..dc469d994 100644
--- a/.github/workflows/build_stm32.yml
+++ b/.github/workflows/build_stm32.yml
@@ -7,6 +7,8 @@ on:
required: true
type: string
+permissions: read-all
+
jobs:
build-stm32:
runs-on: ubuntu-latest
diff --git a/.github/workflows/generate-userprefs.yml b/.github/workflows/generate-userprefs.yml
deleted file mode 100644
index 10dd1ff7d..000000000
--- a/.github/workflows/generate-userprefs.yml
+++ /dev/null
@@ -1,35 +0,0 @@
-name: Generate UsersPrefs JSON manifest
-
-on:
- push:
- paths:
- - userPrefs.h
- branches:
- - master
-
-jobs:
- generate-userprefs:
- runs-on: ubuntu-latest
- steps:
- - name: Checkout code
- uses: actions/checkout@v4
-
- - name: Install Clang
- run: sudo apt-get install -y clang
-
- - name: Install trunk
- run: curl https://get.trunk.io -fsSL | bash
-
- - name: Generate userPrefs.jsom
- run: python3 ./bin/build-userprefs-json.py
-
- - name: Trunk format json
- run: trunk format userPrefs.json
-
- - name: Commit userPrefs.json
- run: |
- git config --global user.email "actions@github.com"
- git config --global user.name "GitHub Actions"
- git add userPrefs.json
- git commit -m "Update userPrefs.json"
- git push
diff --git a/.github/workflows/main_matrix.yml b/.github/workflows/main_matrix.yml
index 7062ef525..da4b4e6f3 100644
--- a/.github/workflows/main_matrix.yml
+++ b/.github/workflows/main_matrix.yml
@@ -135,10 +135,10 @@ jobs:
build_location: local
secrets: inherit
- package-pio-deps-native:
+ package-pio-deps-native-tft:
uses: ./.github/workflows/package_pio_deps.yml
with:
- pio_env: native
+ pio_env: native-tft
secrets: inherit
test-native:
@@ -288,7 +288,7 @@ jobs:
needs:
- gather-artifacts
- build-debian-src
- - package-pio-deps-native
+ - package-pio-deps-native-tft
steps:
- name: Checkout
uses: actions/checkout@v4
@@ -324,10 +324,10 @@ jobs:
merge-multiple: true
path: ./output/debian-src
- - name: Download native pio deps
+ - name: Download `native-tft` pio deps
uses: actions/download-artifact@v4
with:
- pattern: platformio-deps-native-${{ steps.version.outputs.long }}
+ pattern: platformio-deps-native-tft-${{ steps.version.outputs.long }}
merge-multiple: true
path: ./output/pio-deps-native
@@ -352,6 +352,12 @@ jobs:
run: >-
bin/bump_version.py
+ - name: Ensure debian deps are installed
+ shell: bash
+ run: |
+ sudo apt-get update -y --fix-missing
+ sudo apt-get install -y devscripts
+
- name: Update debian changelog
run: >-
debian/ci_changelog.sh
diff --git a/.github/workflows/nightly.yml b/.github/workflows/nightly.yml
index 7a35e2b99..36ec22f17 100644
--- a/.github/workflows/nightly.yml
+++ b/.github/workflows/nightly.yml
@@ -9,7 +9,7 @@ permissions: read-all
jobs:
trunk_check:
name: Trunk Check and Upload
- runs-on: ubuntu-latest
+ runs-on: ubuntu-24.04
steps:
- name: Checkout
@@ -21,8 +21,9 @@ jobs:
trunk-token: ${{ secrets.TRUNK_TOKEN }}
trunk_upgrade:
+ # See: https://github.com/trunk-io/trunk-action/blob/v1/readme.md#automatic-upgrades
name: Trunk Upgrade (PR)
- runs-on: ubuntu-latest
+ runs-on: ubuntu-24.04
permissions:
contents: write # For trunk to create PRs
pull-requests: write # For trunk to create PRs
@@ -30,6 +31,7 @@ jobs:
- name: Checkout
uses: actions/checkout@v4
- # See https://github.com/trunk-io/trunk-action/blob/v1/readme.md#automatic-upgrades
- name: Trunk Upgrade
uses: trunk-io/trunk-action/upgrade@v1
+ with:
+ base: master
diff --git a/.github/workflows/sec_sast_flawfinder.yml b/.github/workflows/sec_sast_flawfinder.yml
deleted file mode 100644
index 99cc72190..000000000
--- a/.github/workflows/sec_sast_flawfinder.yml
+++ /dev/null
@@ -1,41 +0,0 @@
----
-name: Flawfinder Scan
-
-on:
- push:
- branches: [master, develop]
- paths-ignore:
- - "**.md"
- - "version.properties"
-
-jobs:
- flawfinder:
- runs-on: ubuntu-latest
- name: Flawfinder
-
- steps:
- # step 1
- - name: clone application source code
- uses: actions/checkout@v4
-
- # step 2
- - name: flawfinder_scan
- uses: david-a-wheeler/flawfinder@2.0.19
- with:
- arguments: "--sarif ./"
- output: "flawfinder_report.sarif"
-
- # step 3
- - name: save report as pipeline artifact
- uses: actions/upload-artifact@v4
- with:
- name: flawfinder_report.sarif
- overwrite: true
- path: flawfinder_report.sarif
-
- # step 4
- - name: publish code scanning alerts
- uses: github/codeql-action/upload-sarif@v3
- with:
- sarif_file: flawfinder_report.sarif
- category: flawfinder
diff --git a/.github/workflows/sec_sast_semgrep_cron.yml b/.github/workflows/sec_sast_semgrep_cron.yml
index 54bbbe6d2..944103562 100644
--- a/.github/workflows/sec_sast_semgrep_cron.yml
+++ b/.github/workflows/sec_sast_semgrep_cron.yml
@@ -3,10 +3,10 @@ name: Semgrep Full Scan
on:
workflow_dispatch:
- branches:
- - master
schedule:
- - cron: "0 1 * * 6"
+ - cron: 0 1 * * 6
+
+permissions: read-all
jobs:
semgrep-full:
diff --git a/.github/workflows/sec_sast_semgrep_pull.yml b/.github/workflows/sec_sast_semgrep_pull.yml
index 9013f1c74..527a5c076 100644
--- a/.github/workflows/sec_sast_semgrep_pull.yml
+++ b/.github/workflows/sec_sast_semgrep_pull.yml
@@ -2,6 +2,8 @@
name: Semgrep Differential Scan
on: pull_request
+permissions: read-all
+
jobs:
semgrep-diff:
runs-on: ubuntu-22.04
diff --git a/.github/workflows/stale_bot.yml b/.github/workflows/stale_bot.yml
index 0ce0579de..19b7cf7fd 100644
--- a/.github/workflows/stale_bot.yml
+++ b/.github/workflows/stale_bot.yml
@@ -16,7 +16,7 @@ jobs:
steps:
- name: Stale PR+Issues
- uses: actions/stale@v9.0.0
+ uses: actions/stale@v9.1.0
with:
exempt-issue-labels: pinned,3.0
exempt-pr-labels: pinned,3.0
diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml
index c9489db1a..0f0ee0af4 100644
--- a/.github/workflows/tests.yml
+++ b/.github/workflows/tests.yml
@@ -2,9 +2,11 @@ name: End to end tests
on:
schedule:
- - cron: "0 0 * * *" # Run every day at midnight
+ - cron: 0 0 * * * # Run every day at midnight
workflow_dispatch: {}
+permissions: read-all
+
jobs:
native-tests:
uses: ./.github/workflows/test_native.yml
diff --git a/.github/workflows/trunk_annotate.pr.yml b/.github/workflows/trunk_annotate_pr.yml
similarity index 95%
rename from .github/workflows/trunk_annotate.pr.yml
rename to .github/workflows/trunk_annotate_pr.yml
index ac5cdc0d5..62c1c01b7 100644
--- a/.github/workflows/trunk_annotate.pr.yml
+++ b/.github/workflows/trunk_annotate_pr.yml
@@ -11,7 +11,7 @@ permissions: read-all
jobs:
trunk_check:
name: Trunk Code Quality Annotate
- runs-on: ubuntu-latest
+ runs-on: ubuntu-24.04
permissions:
checks: write # For trunk to post annotations
contents: read # For repo checkout
diff --git a/.github/workflows/trunk_check.yml b/.github/workflows/trunk_check.yml
index 6ed905bc8..55656bf48 100644
--- a/.github/workflows/trunk_check.yml
+++ b/.github/workflows/trunk_check.yml
@@ -9,7 +9,7 @@ permissions: read-all
jobs:
trunk_check:
name: Trunk Check Runner
- runs-on: ubuntu-latest
+ runs-on: ubuntu-24.04
permissions:
checks: write # For trunk to post annotations
contents: read # For repo checkout
@@ -20,3 +20,5 @@ jobs:
- name: Trunk Check
uses: trunk-io/trunk-action@v1
+ with:
+ save-annotations: true
diff --git a/.github/workflows/trunk_format_pr.yml b/.github/workflows/trunk_format_pr.yml
index 0d6eb6041..33f4182eb 100644
--- a/.github/workflows/trunk_format_pr.yml
+++ b/.github/workflows/trunk_format_pr.yml
@@ -4,11 +4,15 @@ on:
issue_comment:
types: [created]
+permissions: read-all
+
jobs:
trunk-fmt:
if: github.event.issue.pull_request != null && contains(github.event.comment.body, 'trunk fmt')
runs-on: ubuntu-latest
-
+ permissions:
+ contents: write
+ pull-requests: write
steps:
- name: Checkout repository
uses: actions/checkout@v4
diff --git a/.github/workflows/update_protobufs.yml b/.github/workflows/update_protobufs.yml
index e7b3c1f40..5aa295b89 100644
--- a/.github/workflows/update_protobufs.yml
+++ b/.github/workflows/update_protobufs.yml
@@ -1,10 +1,14 @@
name: Update protobufs and regenerate classes
on: workflow_dispatch
+permissions: read-all
+
jobs:
update-protobufs:
runs-on: ubuntu-latest
-
+ permissions:
+ contents: write
+ pull-requests: write
steps:
- name: Checkout code
uses: actions/checkout@v4
diff --git a/.gitmodules b/.gitmodules
index 7c54ad513..964204476 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -1,6 +1,9 @@
[submodule "protobufs"]
path = protobufs
url = https://github.com/meshtastic/protobufs.git
+[submodule "lib/device-ui"]
+ path = lib/device-ui
+ url = https://github.com/meshtastic/device-ui.git
[submodule "meshtestic"]
path = meshtestic
url = https://github.com/meshtastic/meshTestic
diff --git a/.trunk/configs/.clang-tidy b/.trunk/configs/.clang-tidy
new file mode 100644
index 000000000..e4bd819fa
--- /dev/null
+++ b/.trunk/configs/.clang-tidy
@@ -0,0 +1,39 @@
+Checks: >-
+ bugprone-*,
+ cppcoreguidelines-*,
+ google-*,
+ misc-*,
+ modernize-*,
+ performance-*,
+ readability-*,
+ -bugprone-lambda-function-name,
+ -bugprone-reserved-identifier,
+ -cppcoreguidelines-avoid-goto,
+ -cppcoreguidelines-avoid-magic-numbers,
+ -cppcoreguidelines-avoid-non-const-global-variables,
+ -cppcoreguidelines-pro-bounds-array-to-pointer-decay,
+ -cppcoreguidelines-pro-type-vararg,
+ -google-readability-braces-around-statements,
+ -google-readability-function-size,
+ -misc-no-recursion,
+ -modernize-return-braced-init-list,
+ -modernize-use-nodiscard,
+ -modernize-use-trailing-return-type,
+ -performance-unnecessary-value-param,
+ -readability-magic-numbers,
+
+CheckOptions:
+ - key: readability-function-cognitive-complexity.Threshold
+ value: 100
+ - key: readability-function-cognitive-complexity.IgnoreMacros
+ value: true
+ # Set naming conventions for your style below (there are dozens of naming settings possible):
+ # See https://clang.llvm.org/extra/clang-tidy/checks/readability/identifier-naming.html
+ # - key: readability-identifier-naming.ClassCase
+ # value: CamelCase
+ # - key: readability-identifier-naming.NamespaceCase
+ # value: lower_case
+ # - key: readability-identifier-naming.PrivateMemberSuffix
+ # value: _
+ # - key: readability-identifier-naming.StructCase
+ # value: CamelCase
diff --git a/.trunk/configs/.markdownlint.yaml b/.trunk/configs/.markdownlint.yaml
index fb940393d..6486f050e 100644
--- a/.trunk/configs/.markdownlint.yaml
+++ b/.trunk/configs/.markdownlint.yaml
@@ -8,3 +8,4 @@ line_length: false
spaces: false
url: false
whitespace: false
+headings: false
diff --git a/.trunk/trunk.yaml b/.trunk/trunk.yaml
index f2393592c..78fdb8e45 100644
--- a/.trunk/trunk.yaml
+++ b/.trunk/trunk.yaml
@@ -1,37 +1,36 @@
version: 0.1
cli:
- version: 1.22.8
+ version: 1.22.10
plugins:
sources:
- id: trunk
- ref: v1.6.6
+ ref: v1.6.7
uri: https://github.com/trunk-io/plugins
lint:
enabled:
- - prettier@3.4.2
- - trufflehog@3.86.1
+ - prettier@3.5.2
+ - trufflehog@3.88.14
- yamllint@1.35.1
- - bandit@1.8.0
- - checkov@3.2.334
+ - bandit@1.8.3
+ - checkov@3.2.378
- terrascan@1.19.9
- - trivy@0.58.0
- #- trufflehog@3.63.2-rc0
+ - trivy@0.59.1
- taplo@0.9.3
- - ruff@0.8.3
- - isort@5.13.2
- - markdownlint@0.43.0
- - oxipng@9.1.3
+ - ruff@0.9.7
+ - isort@6.0.1
+ - markdownlint@0.44.0
+ - oxipng@9.1.4
- svgo@3.3.2
- - actionlint@1.7.4
- - flake8@7.1.1
+ - actionlint@1.7.7
+ - flake8@7.1.2
- hadolint@2.12.1-beta
- shfmt@3.6.0
- shellcheck@0.10.0
- - black@24.10.0
+ - black@25.1.0
- git-diff-check
- - gitleaks@8.21.2
+ - gitleaks@8.24.0
- clang-format@16.0.3
- #- prettier@3.3.3
+ - clang-tidy@16.0.3
ignore:
- linters: [ALL]
paths:
diff --git a/Dockerfile b/Dockerfile
index f9a3b9962..fd1bb6164 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -1,21 +1,23 @@
# trunk-ignore-all(terrascan/AC_DOCKER_0002): Known terrascan issue
-# trunk-ignore-all(hadolint/DL3008): Use latest version of apt packages for buildchain
# trunk-ignore-all(trivy/DS002): We must run as root for this container
# trunk-ignore-all(checkov/CKV_DOCKER_8): We must run as root for this container
# trunk-ignore-all(hadolint/DL3002): We must run as root for this container
+# trunk-ignore-all(hadolint/DL3008): Do not pin apt package versions
+# trunk-ignore-all(hadolint/DL3013): Do not pin pip package versions
-FROM python:3.12-bookworm AS builder
+FROM python:3.13-bookworm AS builder
ENV DEBIAN_FRONTEND=noninteractive
ENV TZ=Etc/UTC
# Install Dependencies
ENV PIP_ROOT_USER_ACTION=ignore
-RUN apt-get update && apt-get install --no-install-recommends -y wget g++ zip git ca-certificates \
+RUN apt-get update && apt-get install --no-install-recommends -y \
+ wget g++ zip git ca-certificates \
libgpiod-dev libyaml-cpp-dev libbluetooth-dev libi2c-dev \
- libusb-1.0-0-dev libulfius-dev liborcania-dev libssl-dev pkg-config && \
- apt-get clean && rm -rf /var/lib/apt/lists/* && \
- pip install --no-cache-dir -U platformio==6.1.16 && \
- mkdir /tmp/firmware
+ libusb-1.0-0-dev libulfius-dev liborcania-dev libssl-dev pkg-config \
+ && apt-get clean && rm -rf /var/lib/apt/lists/* \
+ && pip install --no-cache-dir -U platformio \
+ && mkdir /tmp/firmware
# Copy source code
WORKDIR /tmp/firmware
@@ -35,8 +37,9 @@ ENV TZ=Etc/UTC
# nosemgrep: dockerfile.security.last-user-is-root.last-user-is-root
USER root
-RUN apt-get update && apt-get --no-install-recommends -y install libc-bin libc6 libgpiod2 libyaml-cpp0.7 libi2c0 libulfius2.7 libusb-1.0-0-dev liborcania2.3 libssl3 && \
- apt-get clean && rm -rf /var/lib/apt/lists/* \
+RUN apt-get update && apt-get --no-install-recommends -y install \
+ libc-bin libc6 libgpiod2 libyaml-cpp0.7 libi2c0 libulfius2.7 libusb-1.0-0-dev liborcania2.3 libssl3 \
+ && apt-get clean && rm -rf /var/lib/apt/lists/* \
&& mkdir -p /var/lib/meshtasticd \
&& mkdir -p /etc/meshtasticd/config.d \
&& mkdir -p /etc/meshtasticd/ssl
diff --git a/alpine.Dockerfile b/alpine.Dockerfile
index 8b48eeca3..b6d91a75a 100644
--- a/alpine.Dockerfile
+++ b/alpine.Dockerfile
@@ -1,14 +1,18 @@
# trunk-ignore-all(trivy/DS002): We must run as root for this container
# trunk-ignore-all(checkov/CKV_DOCKER_8): We must run as root for this container
# trunk-ignore-all(hadolint/DL3002): We must run as root for this container
+# trunk-ignore-all(hadolint/DL3018): Do not pin apk package versions
+# trunk-ignore-all(hadolint/DL3013): Do not pin pip package versions
-FROM python:3.12-alpine3.21 AS builder
+FROM python:3.13-alpine3.21 AS builder
ENV PIP_ROOT_USER_ACTION=ignore
-RUN apk add bash g++ libstdc++-dev linux-headers zip git ca-certificates libgpiod-dev yaml-cpp-dev bluez-dev \
- libusb-dev i2c-tools-dev openssl-dev pkgconf argp-standalone && \
- pip install --no-cache-dir -U platformio==6.1.16 && \
- mkdir /tmp/firmware
+RUN apk --no-cache add \
+ bash g++ libstdc++-dev linux-headers zip git ca-certificates libgpiod-dev yaml-cpp-dev bluez-dev \
+ libusb-dev i2c-tools-dev openssl-dev pkgconf argp-standalone \
+ && rm -rf /var/cache/apk/* \
+ && pip install --no-cache-dir -U platformio \
+ && mkdir /tmp/firmware
WORKDIR /tmp/firmware
COPY . /tmp/firmware
@@ -27,7 +31,9 @@ FROM alpine:3.21
# nosemgrep: dockerfile.security.last-user-is-root.last-user-is-root
USER root
-RUN apk add libstdc++ libgpiod yaml-cpp libusb i2c-tools \
+RUN apk --no-cache add \
+ libstdc++ libgpiod yaml-cpp libusb i2c-tools \
+ && rm -rf /var/cache/apk/* \
&& mkdir -p /var/lib/meshtasticd \
&& mkdir -p /etc/meshtasticd/config.d \
&& mkdir -p /etc/meshtasticd/ssl
diff --git a/arch/esp32/esp32.ini b/arch/esp32/esp32.ini
index d6a756bec..256781ba1 100644
--- a/arch/esp32/esp32.ini
+++ b/arch/esp32/esp32.ini
@@ -2,7 +2,7 @@
[esp32_base]
extends = arduino_base
custom_esp32_kind = esp32
-platform = platformio/espressif32@6.9.0
+platform = platformio/espressif32@6.10.0
build_src_filter =
${arduino_base.build_src_filter} - - - - -
@@ -37,6 +37,7 @@ build_flags =
-DLIBPAX_ARDUINO
-DLIBPAX_WIFI
-DLIBPAX_BLE
+ -DHAS_UDP_MULTICAST=1
;-DDEBUG_HEAP
lib_deps =
@@ -45,9 +46,9 @@ lib_deps =
${environmental_base.lib_deps}
${radiolib_base.lib_deps}
https://github.com/meshtastic/esp32_https_server.git#23665b3adc080a311dcbb586ed5941b5f94d6ea2
- h2zero/NimBLE-Arduino@^1.4.2
+ h2zero/NimBLE-Arduino@^1.4.3
https://github.com/dbinfrago/libpax.git#3cdc0371c375676a97967547f4065607d4c53fd1
- lewisxhe/XPowersLib@^0.2.6
+ lewisxhe/XPowersLib@^0.2.7
https://github.com/meshtastic/ESP32_Codec2.git#633326c78ac251c059ab3a8c430fcdf25b41672f
rweather/Crypto@^0.4.0
@@ -65,4 +66,4 @@ lib_ignore =
; customize the partition table
; http://docs.platformio.org/en/latest/platforms/espressif32.html#partition-tables
-board_build.partitions = partition-table.csv
\ No newline at end of file
+board_build.partitions = partition-table.csv
diff --git a/arch/esp32/esp32c6.ini b/arch/esp32/esp32c6.ini
index 3f8b1bdbe..d0425812f 100644
--- a/arch/esp32/esp32c6.ini
+++ b/arch/esp32/esp32c6.ini
@@ -24,7 +24,7 @@ lib_deps =
${networking_base.lib_deps}
${environmental_base.lib_deps}
${radiolib_base.lib_deps}
- lewisxhe/XPowersLib@^0.2.6
+ lewisxhe/XPowersLib@^0.2.7
https://github.com/meshtastic/ESP32_Codec2.git#633326c78ac251c059ab3a8c430fcdf25b41672f
rweather/Crypto@^0.4.0
@@ -38,4 +38,4 @@ lib_ignore =
NonBlockingRTTTL
NimBLE-Arduino
libpax
-
\ No newline at end of file
+
diff --git a/arch/nrf52/nrf52.ini b/arch/nrf52/nrf52.ini
index b68977c78..606cabac6 100644
--- a/arch/nrf52/nrf52.ini
+++ b/arch/nrf52/nrf52.ini
@@ -4,8 +4,8 @@ platform = platformio/nordicnrf52@^10.7.0
extends = arduino_base
platform_packages =
; our custom Git version until they merge our PR
- framework-arduinoadafruitnrf52 @ https://github.com/meshtastic/Adafruit_nRF52_Arduino.git#e13f5820002a4fb2a5e6754b42ace185277e5adf
- toolchain-gccarmnoneeabi@~1.90301.0
+ platformio/framework-arduinoadafruitnrf52 @ https://github.com/meshtastic/Adafruit_nRF52_Arduino.git#e13f5820002a4fb2a5e6754b42ace185277e5adf
+ platformio/toolchain-gccarmnoneeabi@~1.90301.0
build_type = debug
build_flags =
diff --git a/arch/rp2xx0/rp2040.ini b/arch/rp2xx0/rp2040.ini
index 5cfa678d5..74644800d 100644
--- a/arch/rp2xx0/rp2040.ini
+++ b/arch/rp2xx0/rp2040.ini
@@ -18,6 +18,7 @@ build_src_filter =
lib_ignore =
BluetoothOTA
+ lvgl
lib_deps =
${arduino_base.lib_deps}
diff --git a/arch/rp2xx0/rp2350.ini b/arch/rp2xx0/rp2350.ini
index ab16e24b4..6f1e4400e 100644
--- a/arch/rp2xx0/rp2350.ini
+++ b/arch/rp2xx0/rp2350.ini
@@ -1,8 +1,8 @@
; Common settings for rp2040 Processor based targets
[rp2350_base]
-platform = https://github.com/maxgerhardt/platform-raspberrypi.git#19e30129fb1428b823be585c787dcb4ac0d9014c ; For arduino-pico >=4.2.1
+platform = https://github.com/maxgerhardt/platform-raspberrypi.git#76ecf3c7e9dd4503af0331154c4ca1cddc4b03e5 ; For arduino-pico >= 4.4.3
extends = arduino_base
-platform_packages = framework-arduinopico@https://github.com/earlephilhower/arduino-pico.git#6024e9a7e82a72e38dd90f42029ba3748835eb2e ; 4.3.0 with fix MDNS
+platform_packages = framework-arduinopico@https://github.com/earlephilhower/arduino-pico.git#4.4.3
board_build.core = earlephilhower
board_build.filesystem_size = 0.5m
@@ -10,7 +10,6 @@ build_flags =
${arduino_base.build_flags} -Wno-unused-variable -Wcast-align
-Isrc/platform/rp2xx0
-D__PLAT_RP2350__
-# -D _POSIX_THREADS
build_src_filter =
${arduino_base.build_src_filter} - - - - - - - - - - -
diff --git a/arch/stm32/stm32.ini b/arch/stm32/stm32.ini
index 46f41db3a..efa1ab0e4 100644
--- a/arch/stm32/stm32.ini
+++ b/arch/stm32/stm32.ini
@@ -1,7 +1,7 @@
[stm32_base]
extends = arduino_base
-platform = ststm32
-platform_packages = platformio/framework-arduinoststm32@https://github.com/stm32duino/Arduino_Core_STM32.git#ea74156acd823b6d14739f389e6cdc648f8ee36e
+platform = platformio/ststm32
+platform_packages = platformio/framework-arduinoststm32@^4.20900.0
build_type = release
diff --git a/bin/build-esp32.sh b/bin/build-esp32.sh
index f8d808ced..a0635e997 100755
--- a/bin/build-esp32.sh
+++ b/bin/build-esp32.sh
@@ -35,11 +35,11 @@ cp $SRCBIN $OUTDIR/$basename-update.bin
echo "Building Filesystem for ESP32 targets"
pio run --environment $1 -t buildfs
-cp .pio/build/$1/littlefs.bin $OUTDIR/littlefswebui-$VERSION.bin
+cp .pio/build/$1/littlefs.bin $OUTDIR/littlefswebui-$1-$VERSION.bin
# Remove webserver files from the filesystem and rebuild
ls -l data/static # Diagnostic list of files
rm -rf data/static
pio run --environment $1 -t buildfs
-cp .pio/build/$1/littlefs.bin $OUTDIR/littlefs-$VERSION.bin
+cp .pio/build/$1/littlefs.bin $OUTDIR/littlefs-$1-$VERSION.bin
cp bin/device-install.* $OUTDIR
-cp bin/device-update.* $OUTDIR
+cp bin/device-update.* $OUTDIR
\ No newline at end of file
diff --git a/bin/build-native.sh b/bin/build-native.sh
index cda77b064..c6b1434dd 100755
--- a/bin/build-native.sh
+++ b/bin/build-native.sh
@@ -24,7 +24,7 @@ mkdir -p $OUTDIR/
rm -r $OUTDIR/* || true
# Important to pull latest version of libs into all device flavors, otherwise some devices might be stale
-platformio pkg update --environment native || platformioFailed
+pio pkg update --environment native || platformioFailed
pio run --environment native || platformioFailed
cp .pio/build/native/program "$OUTDIR/meshtasticd_linux_$(uname -m)"
cp bin/native-install.* $OUTDIR
diff --git a/bin/config.d/MUI/X11_480x480.yaml b/bin/config.d/MUI/X11_480x480.yaml
new file mode 100644
index 000000000..7bdf50453
--- /dev/null
+++ b/bin/config.d/MUI/X11_480x480.yaml
@@ -0,0 +1,4 @@
+Display:
+ Panel: X11
+ Width: 480
+ Height: 480
\ No newline at end of file
diff --git a/bin/config.d/lora-starter-edition-sx1262-i2c.yaml b/bin/config.d/lora-starter-edition-sx1262-i2c.yaml
new file mode 100644
index 000000000..d9b64c7da
--- /dev/null
+++ b/bin/config.d/lora-starter-edition-sx1262-i2c.yaml
@@ -0,0 +1,10 @@
+# https://www.waveshare.com/core1262-868m.htm
+# https://github.com/markbirss/lora-starter-edition-sx1262-i2c
+Lora:
+ Module: sx1262 # Starter Edition SX1262 I2C Raspberry Pi HAT
+ DIO2_AS_RF_SWITCH: true
+ DIO3_TCXO_VOLTAGE: true
+ CS: 8
+ IRQ: 22
+ Busy: 4
+ Reset: 18
diff --git a/bin/config.d/lora-ws-raspberry-pi-pico-to-rpi-adapter.yaml b/bin/config.d/lora-ws-raspberry-pi-pico-to-rpi-adapter.yaml
new file mode 100644
index 000000000..1e1c325e7
--- /dev/null
+++ b/bin/config.d/lora-ws-raspberry-pi-pico-to-rpi-adapter.yaml
@@ -0,0 +1,10 @@
+# https://www.waveshare.com/pico-lora-sx1262-868m.htm
+# https://github.com/markbirss/lora-ws-raspberry-pi-pico-to-rpi-adapter
+Lora:
+ Module: sx1262 # Waveshare Raspberry Pi Pico to Raspberry Pi HAT Adapter
+ DIO2_AS_RF_SWITCH: true
+ DIO3_TCXO_VOLTAGE: true
+ CS: 21
+ IRQ: 16
+ Busy: 20
+ Reset: 18
diff --git a/bin/generate_ci_matrix.py b/bin/generate_ci_matrix.py
index 4d8759ecc..7513ccff5 100755
--- a/bin/generate_ci_matrix.py
+++ b/bin/generate_ci_matrix.py
@@ -35,6 +35,11 @@ for subdir, dirs, files in os.walk(rootdir):
outlist.append(section)
else:
outlist.append(section)
+ # Add the TFT variants if the base variant is selected
+ elif section.replace("-tft", "") in outlist and config[config[c].name].get("board_level") != "extra":
+ outlist.append(section)
+ elif section.replace("-inkhud", "") in outlist and config[config[c].name].get("board_level") != "extra":
+ outlist.append(section)
if "board_check" in config[config[c].name]:
if (config[config[c].name]["board_check"] == "true") & (
"check" in options
@@ -43,4 +48,4 @@ for subdir, dirs, files in os.walk(rootdir):
if ("quick" in options) & (len(outlist) > 3):
print(json.dumps(random.sample(outlist, 3)))
else:
- print(json.dumps(outlist))
+ print(json.dumps(outlist))
\ No newline at end of file
diff --git a/debian/control b/debian/control
index bb79d1958..b3a8eb58e 100644
--- a/debian/control
+++ b/debian/control
@@ -3,6 +3,7 @@ Section: misc
Priority: optional
Maintainer: Austin Lane
Build-Depends: debhelper-compat (= 13),
+ lsb-release,
tar,
gzip,
platformio,
diff --git a/debian/rules b/debian/rules
index a1a27c2f2..0612ba352 100755
--- a/debian/rules
+++ b/debian/rules
@@ -11,6 +11,15 @@ PIO_ENV:=\
PLATFORMIO_LIBDEPS_DIR=pio/libdeps \
PLATFORMIO_PACKAGES_DIR=pio/packages
+# Raspbian armhf builds should be compatible with armv6-hardfloat
+# https://www.valvers.com/open-software/raspberry-pi/bare-metal-programming-in-c-part-1/#rpi1-compiler-flags
+ifneq (,$(findstring Raspbian,$(shell lsb_release -is)))
+ifeq ($(DEB_BUILD_ARCH),armhf)
+PIO_ENV+=\
+ PLATFORMIO_BUILD_FLAGS="-mfloat-abi=hard -mfpu=vfp -march=armv6zk"
+endif
+endif
+
override_dh_auto_build:
# Extract tarballs within source deb
tar -xf pio.tar
diff --git a/lib/device-ui b/lib/device-ui
new file mode 160000
index 000000000..5c6156d2a
--- /dev/null
+++ b/lib/device-ui
@@ -0,0 +1 @@
+Subproject commit 5c6156d2aa10d62cca3e57ffc117b934ef2fbffe
diff --git a/monitor/filter_c3_exception_decoder.py b/monitor/filter_c3_exception_decoder.py
index 6d7b5370c..5e74dc2b9 100644
--- a/monitor/filter_c3_exception_decoder.py
+++ b/monitor/filter_c3_exception_decoder.py
@@ -1,3 +1,6 @@
+# trunk-ignore-all(bandit/B404): subprocess is used to call addr2line
+# trunk-ignore-all(bandit/B603): subprocess is used to call addr2line
+
# Copyright (c) 2014-present PlatformIO
#
# Licensed under the Apache License, Version 2.0 (the "License");
diff --git a/platformio.ini b/platformio.ini
index 171d6c829..1875c5324 100644
--- a/platformio.ini
+++ b/platformio.ini
@@ -60,7 +60,7 @@ lib_deps =
https://github.com/meshtastic/arduino-fsm.git#7db3702bf0cfe97b783d6c72595e3f38e0b19159
https://github.com/meshtastic/TinyGPSPlus.git#71a82db35f3b973440044c476d4bcdc673b104f4
https://github.com/meshtastic/ArduinoThread.git#1ae8778c85d0a2a729f989e0b1e7d7c4dc84eef0
- nanopb/Nanopb@0.4.9
+ nanopb/Nanopb@0.4.91
erriez/ErriezCRC32@1.0.1
; Used for the code analysis in PIO Home / Inspect
diff --git a/protobufs b/protobufs
index 068646653..2a3a67f04 160000
--- a/protobufs
+++ b/protobufs
@@ -1 +1 @@
-Subproject commit 068646653e8375fc145988026ad242a3cf70f7ab
+Subproject commit 2a3a67f0431926dc3f32a8b216d264daab09b9bf
diff --git a/src/BluetoothStatus.h b/src/BluetoothStatus.h
new file mode 100644
index 000000000..e29139001
--- /dev/null
+++ b/src/BluetoothStatus.h
@@ -0,0 +1,105 @@
+#pragma once
+#include "Status.h"
+#include "assert.h"
+#include "configuration.h"
+#include "meshUtils.h"
+#include
+
+namespace meshtastic
+{
+
+// Describes the state of the Bluetooth connection
+// Allows display to handle pairing events without each UI needing to explicitly hook the Bluefruit / NimBLE code
+class BluetoothStatus : public Status
+{
+ public:
+ enum class ConnectionState {
+ DISCONNECTED,
+ PAIRING,
+ CONNECTED,
+ };
+
+ private:
+ CallbackObserver statusObserver =
+ CallbackObserver(this, &BluetoothStatus::updateStatus);
+
+ ConnectionState state = ConnectionState::DISCONNECTED;
+ std::string passkey; // Stored as string, because Bluefruit allows passkeys with a leading zero
+
+ public:
+ BluetoothStatus() { statusType = STATUS_TYPE_BLUETOOTH; }
+
+ // New BluetoothStatus: connected or disconnected
+ BluetoothStatus(ConnectionState state)
+ {
+ assert(state != ConnectionState::PAIRING); // If pairing, use constructor which specifies passkey
+ statusType = STATUS_TYPE_BLUETOOTH;
+ this->state = state;
+ }
+
+ // New BluetoothStatus: pairing, with passkey
+ BluetoothStatus(std::string passkey) : Status()
+ {
+ statusType = STATUS_TYPE_BLUETOOTH;
+ this->state = ConnectionState::PAIRING;
+ this->passkey = passkey;
+ }
+
+ ConnectionState getConnectionState() const { return this->state; }
+
+ std::string getPasskey() const
+ {
+ assert(state == ConnectionState::PAIRING);
+ return this->passkey;
+ }
+
+ void observe(Observable *source) { statusObserver.observe(source); }
+
+ bool matches(const BluetoothStatus *newStatus) const
+ {
+ if (this->state == newStatus->getConnectionState()) {
+ // Same state: CONNECTED / DISCONNECTED
+ if (this->state != ConnectionState::PAIRING)
+ return true;
+ // Same state: PAIRING, and passkey matches
+ else if (this->getPasskey() == newStatus->getPasskey())
+ return true;
+ }
+
+ return false;
+ }
+
+ int updateStatus(const BluetoothStatus *newStatus)
+ {
+ // Has the status changed?
+ if (!matches(newStatus)) {
+ // Copy the members
+ state = newStatus->getConnectionState();
+ if (state == ConnectionState::PAIRING)
+ passkey = newStatus->getPasskey();
+
+ // Tell anyone interested that we have an update
+ onNewStatus.notifyObservers(this);
+
+ // Debug only:
+ switch (state) {
+ case ConnectionState::PAIRING:
+ LOG_DEBUG("BluetoothStatus PAIRING, key=%s", passkey.c_str());
+ break;
+ case ConnectionState::CONNECTED:
+ LOG_DEBUG("BluetoothStatus CONNECTED");
+ break;
+
+ case ConnectionState::DISCONNECTED:
+ LOG_DEBUG("BluetoothStatus DISCONNECTED");
+ break;
+ }
+ }
+
+ return 0;
+ }
+};
+
+} // namespace meshtastic
+
+extern meshtastic::BluetoothStatus *bluetoothStatus;
\ No newline at end of file
diff --git a/src/ButtonThread.cpp b/src/ButtonThread.cpp
index 5175a2680..ec0bc5fc2 100644
--- a/src/ButtonThread.cpp
+++ b/src/ButtonThread.cpp
@@ -11,6 +11,7 @@
#include "main.h"
#include "modules/ExternalNotificationModule.h"
#include "power.h"
+#include "sleep.h"
#ifdef ARCH_PORTDUINO
#include "platform/portduino/PortduinoGlue.h"
#endif
@@ -99,6 +100,13 @@ ButtonThread::ButtonThread() : OSThread("Button")
userButtonTouch.attachLongPressStart(touchPressedLongStart); // Better handling with longpress than click?
#endif
+#ifdef ARCH_ESP32
+ // Register callbacks for before and after lightsleep
+ // Used to detach and reattach interrupts
+ lsObserver.observe(¬ifyLightSleep);
+ lsEndObserver.observe(¬ifyLightSleepEnd);
+#endif
+
attachButtonInterrupts();
#endif
}
@@ -320,6 +328,26 @@ void ButtonThread::detachButtonInterrupts()
#endif
}
+#ifdef ARCH_ESP32
+
+// Detach our class' interrupts before lightsleep
+// Allows sleep.cpp to configure its own interrupts, which wake the device on user-button press
+int ButtonThread::beforeLightSleep(void *unused)
+{
+ detachButtonInterrupts();
+ return 0; // Indicates success
+}
+
+// Reconfigure our interrupts
+// Our class' interrupts were disconnected during sleep, to allow the user button to wake the device from sleep
+int ButtonThread::afterLightSleep(esp_sleep_wakeup_cause_t cause)
+{
+ attachButtonInterrupts();
+ return 0; // Indicates success
+}
+
+#endif
+
/**
* Watch a GPIO and if we get an IRQ, wake the main thread.
* Use to add wake on button press
diff --git a/src/ButtonThread.h b/src/ButtonThread.h
index a01a1718f..54b833d03 100644
--- a/src/ButtonThread.h
+++ b/src/ButtonThread.h
@@ -37,6 +37,12 @@ class ButtonThread : public concurrency::OSThread
void detachButtonInterrupts();
void storeClickCount();
+ // Disconnect and reconnect interrupts for light sleep
+#ifdef ARCH_ESP32
+ int beforeLightSleep(void *unused);
+ int afterLightSleep(esp_sleep_wakeup_cause_t cause);
+#endif
+
private:
#if defined(BUTTON_PIN) || defined(ARCH_PORTDUINO) || defined(USERPREFS_BUTTON_PIN)
static OneButton userButton; // Static - accessed from an interrupt
@@ -48,6 +54,14 @@ class ButtonThread : public concurrency::OSThread
OneButton userButtonTouch;
#endif
+#ifdef ARCH_ESP32
+ // Get notified when lightsleep begins and ends
+ CallbackObserver lsObserver =
+ CallbackObserver(this, &ButtonThread::beforeLightSleep);
+ CallbackObserver lsEndObserver =
+ CallbackObserver(this, &ButtonThread::afterLightSleep);
+#endif
+
// set during IRQ
static volatile ButtonEventType btnEvent;
diff --git a/src/FSCommon.cpp b/src/FSCommon.cpp
index 461c72c26..31fe69c93 100644
--- a/src/FSCommon.cpp
+++ b/src/FSCommon.cpp
@@ -23,6 +23,10 @@ SPIClass SPI1(HSPI);
#define SDHandler SPI
#endif
+#ifndef SD_SPI_FREQUENCY
+#define SD_SPI_FREQUENCY 4000000U
+#endif
+
#endif // HAS_SDCARD
#if defined(ARCH_STM32WL)
@@ -361,8 +365,7 @@ void setupSDCard()
#ifdef HAS_SDCARD
concurrency::LockGuard g(spiLock);
SDHandler.begin(SPI_SCK, SPI_MISO, SPI_MOSI);
-
- if (!SD.begin(SDCARD_CS, SDHandler)) {
+ if (!SD.begin(SDCARD_CS, SDHandler, SD_SPI_FREQUENCY)) {
LOG_DEBUG("No SD_MMC card detected");
return;
}
diff --git a/src/Status.h b/src/Status.h
index 65f3a252f..59d443ab7 100644
--- a/src/Status.h
+++ b/src/Status.h
@@ -7,6 +7,7 @@
#define STATUS_TYPE_POWER 1
#define STATUS_TYPE_GPS 2
#define STATUS_TYPE_NODE 3
+#define STATUS_TYPE_BLUETOOTH 4
namespace meshtastic
{
diff --git a/src/detect/ScanI2CTwoWire.cpp b/src/detect/ScanI2CTwoWire.cpp
index 880e5c131..41cfe1517 100644
--- a/src/detect/ScanI2CTwoWire.cpp
+++ b/src/detect/ScanI2CTwoWire.cpp
@@ -244,6 +244,10 @@ void ScanI2CTwoWire::scanPort(I2CPort port, uint8_t *address, uint8_t asize)
logFoundDevice("BMP-388", (uint8_t)addr.address);
type = BMP_3XX;
break;
+ case 0x60: // BMP-390 should be 0x60
+ logFoundDevice("BMP-390", (uint8_t)addr.address);
+ type = BMP_3XX;
+ break;
case 0x58: // BMP-280 should be 0x58
default:
logFoundDevice("BMP-280", (uint8_t)addr.address);
@@ -521,4 +525,4 @@ void ScanI2CTwoWire::logFoundDevice(const char *device, uint8_t address)
{
LOG_INFO("%s found at address 0x%x", device, address);
}
-#endif
+#endif
\ No newline at end of file
diff --git a/src/detect/einkScan.h b/src/detect/einkScan.h
index 5bc218d00..d20c7b6e5 100644
--- a/src/detect/einkScan.h
+++ b/src/detect/einkScan.h
@@ -6,28 +6,28 @@
void d_writeCommand(uint8_t c)
{
- SPI.beginTransaction(SPISettings(4000000, MSBFIRST, SPI_MODE0));
+ SPI1.beginTransaction(SPISettings(4000000, MSBFIRST, SPI_MODE0));
if (PIN_EINK_DC >= 0)
digitalWrite(PIN_EINK_DC, LOW);
if (PIN_EINK_CS >= 0)
digitalWrite(PIN_EINK_CS, LOW);
- SPI.transfer(c);
+ SPI1.transfer(c);
if (PIN_EINK_CS >= 0)
digitalWrite(PIN_EINK_CS, HIGH);
if (PIN_EINK_DC >= 0)
digitalWrite(PIN_EINK_DC, HIGH);
- SPI.endTransaction();
+ SPI1.endTransaction();
}
void d_writeData(uint8_t d)
{
- SPI.beginTransaction(SPISettings(4000000, MSBFIRST, SPI_MODE0));
+ SPI1.beginTransaction(SPISettings(4000000, MSBFIRST, SPI_MODE0));
if (PIN_EINK_CS >= 0)
digitalWrite(PIN_EINK_CS, LOW);
- SPI.transfer(d);
+ SPI1.transfer(d);
if (PIN_EINK_CS >= 0)
digitalWrite(PIN_EINK_CS, HIGH);
- SPI.endTransaction();
+ SPI1.endTransaction();
}
unsigned long d_waitWhileBusy(uint16_t busy_time)
@@ -53,7 +53,7 @@ unsigned long d_waitWhileBusy(uint16_t busy_time)
void scanEInkDevice(void)
{
- SPI.begin();
+ SPI1.begin();
d_writeCommand(0x22);
d_writeData(0x83);
d_writeCommand(0x20);
@@ -62,6 +62,6 @@ void scanEInkDevice(void)
LOG_DEBUG("EInk display found");
else
LOG_DEBUG("EInk display not found");
- SPI.end();
+ SPI1.end();
}
#endif
\ No newline at end of file
diff --git a/src/gps/GPS.cpp b/src/gps/GPS.cpp
index c2aae0381..2989a59bd 100644
--- a/src/gps/GPS.cpp
+++ b/src/gps/GPS.cpp
@@ -48,8 +48,6 @@ HardwareSerial *GPS::_serial_gps = nullptr;
GPS *gps = nullptr;
-static const char *ACK_SUCCESS_MESSAGE = "Get ack success!";
-
static GPSUpdateScheduling scheduling;
/// Multiple GPS instances might use the same serial port (in sequence), but we can
@@ -437,6 +435,10 @@ static const int serialSpeeds[3] = {9600, 115200, 38400};
static const int rareSerialSpeeds[3] = {4800, 57600, GPS_BAUDRATE};
#endif
+#ifndef GPS_PROBETRIES
+#define GPS_PROBETRIES 2
+#endif
+
/**
* @brief Setup the GPS based on the model detected.
* We detect the GPS by cycling through a set of baud rates, first common then rare.
@@ -460,11 +462,7 @@ bool GPS::setup()
digitalWrite(PIN_GPS_EN, HIGH);
delay(1000);
#endif
-#ifdef TRACKER_T1000_E
- if (probeTries < 5) {
-#else
- if (probeTries < 2) {
-#endif
+ if (probeTries < GPS_PROBETRIES) {
LOG_DEBUG("Probe for GPS at %d", serialSpeeds[speedSelect]);
gnssModel = probe(serialSpeeds[speedSelect]);
if (gnssModel == GNSS_MODEL_UNKNOWN) {
@@ -475,11 +473,7 @@ bool GPS::setup()
}
}
// Rare Serial Speeds
-#ifdef TRACKER_T1000_E
- if (probeTries == 5) {
-#else
- if (probeTries == 2) {
-#endif
+ if (probeTries == GPS_PROBETRIES) {
LOG_DEBUG("Probe for GPS at %d", rareSerialSpeeds[speedSelect]);
gnssModel = probe(rareSerialSpeeds[speedSelect]);
if (gnssModel == GNSS_MODEL_UNKNOWN) {
@@ -1043,14 +1037,6 @@ int32_t GPS::runOnce()
if (config.position.gps_mode != meshtastic_Config_PositionConfig_GpsMode_ENABLED) {
return disable();
}
- // ONCE we will factory reset the GPS for bug #327
- if (!devicestate.did_gps_reset) {
- LOG_WARN("GPS FactoryReset requested");
- if (gps->factoryReset()) { // If we don't succeed try again next time
- devicestate.did_gps_reset = true;
- nodeDB->saveToDisk(SEGMENT_DEVICESTATE);
- }
- }
GPSInitFinished = true;
publishUpdate();
}
@@ -1063,24 +1049,6 @@ int32_t GPS::runOnce()
if (whileActive()) {
// if we have received valid NMEA claim we are connected
setConnected();
- } else {
- if ((config.position.gps_mode == meshtastic_Config_PositionConfig_GpsMode_ENABLED) &&
- IS_ONE_OF(gnssModel, GNSS_MODEL_UBLOX6, GNSS_MODEL_UBLOX7, GNSS_MODEL_UBLOX8, GNSS_MODEL_UBLOX9,
- GNSS_MODEL_UBLOX10)) {
- // reset the GPS on next bootup
- if (devicestate.did_gps_reset && scheduling.elapsedSearchMs() > 60 * 1000UL && !hasFlow()) {
- LOG_DEBUG("GPS is not found, try factory reset on next boot");
- devicestate.did_gps_reset = false;
- nodeDB->saveToDisk(SEGMENT_DEVICESTATE);
- return disable(); // Stop the GPS thread as it can do nothing useful until next reboot.
- }
- }
- }
- // At least one GPS has a bad habit of losing its mind from time to time
- if (rebootsSeen > 2) {
- rebootsSeen = 0;
- LOG_DEBUG("Would normally factoryReset()");
- // gps->factoryReset();
}
// If we're due for an update, wake the GPS
@@ -1415,62 +1383,6 @@ static int32_t toDegInt(RawDegrees d)
return r;
}
-bool GPS::factoryReset()
-{
-#ifdef PIN_GPS_REINIT
- // The L76K GNSS on the T-Echo requires the RESET pin to be pulled LOW
- pinMode(PIN_GPS_REINIT, OUTPUT);
- digitalWrite(PIN_GPS_REINIT, 0);
- delay(150); // The L76K datasheet calls for at least 100MS delay
- digitalWrite(PIN_GPS_REINIT, 1);
-#endif
-
- if (HW_VENDOR == meshtastic_HardwareModel_TBEAM) {
- byte _message_reset1[] = {0xB5, 0x62, 0x06, 0x09, 0x0D, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x1C, 0xA2};
- _serial_gps->write(_message_reset1, sizeof(_message_reset1));
- if (getACK(0x05, 0x01, 10000)) {
- LOG_DEBUG(ACK_SUCCESS_MESSAGE);
- }
- delay(100);
- byte _message_reset2[] = {0xB5, 0x62, 0x06, 0x09, 0x0D, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x1B, 0xA1};
- _serial_gps->write(_message_reset2, sizeof(_message_reset2));
- if (getACK(0x05, 0x01, 10000)) {
- LOG_DEBUG(ACK_SUCCESS_MESSAGE);
- }
- delay(100);
- byte _message_reset3[] = {0xB5, 0x62, 0x06, 0x09, 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x03, 0x1D, 0xB3};
- _serial_gps->write(_message_reset3, sizeof(_message_reset3));
- if (getACK(0x05, 0x01, 10000)) {
- LOG_DEBUG(ACK_SUCCESS_MESSAGE);
- }
- } else if (gnssModel == GNSS_MODEL_MTK) {
- // send the CAS10 to perform a factory restart of the device (and other device that support PCAS statements)
- LOG_INFO("GNSS Factory Reset via PCAS10,3");
- _serial_gps->write("$PCAS10,3*1F\r\n");
- delay(100);
- } else if (gnssModel == GNSS_MODEL_ATGM336H) {
- LOG_INFO("Factory Reset via CAS-CFG-RST");
- uint8_t msglen = makeCASPacket(0x06, 0x02, sizeof(_message_CAS_CFG_RST_FACTORY), _message_CAS_CFG_RST_FACTORY);
- _serial_gps->write(UBXscratch, msglen);
- delay(100);
- } else {
- // fire this for good measure, if we have an L76B - won't harm other devices.
- _serial_gps->write("$PMTK104*37\r\n");
- // No PMTK_ACK for this command.
- delay(100);
- // send the UBLOX Factory Reset Command regardless of detect state, something is very wrong, just assume it's
- // UBLOX. Factory Reset
- byte _message_reset[] = {0xB5, 0x62, 0x06, 0x09, 0x0D, 0x00, 0xFF, 0xFB, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x17, 0x2B, 0x7E};
- _serial_gps->write(_message_reset, sizeof(_message_reset));
- }
- delay(1000);
- return true;
-}
-
/**
* Perform any processing that should be done only while the GPS is awake and looking for a fix.
* Override this method to check for new locations
diff --git a/src/gps/GPS.h b/src/gps/GPS.h
index df85b7cbf..01a4fe745 100644
--- a/src/gps/GPS.h
+++ b/src/gps/GPS.h
@@ -101,8 +101,6 @@ class GPS : private concurrency::OSThread
// Empty the input buffer as quickly as possible
void clearBuffer();
- virtual bool factoryReset();
-
// Creates an instance of the GPS class.
// Returns the new instance or null if the GPS is not present.
static GPS *createGps();
diff --git a/src/graphics/fonts/OLEDDisplayFontsPL.cpp b/src/graphics/fonts/OLEDDisplayFontsPL.cpp
index 1f43967aa..0767e24e7 100644
--- a/src/graphics/fonts/OLEDDisplayFontsPL.cpp
+++ b/src/graphics/fonts/OLEDDisplayFontsPL.cpp
@@ -1,1312 +1,1313 @@
+// trunk-ignore-all(clang-format): Preserve long lines
#include "OLEDDisplayFontsPL.h"
const uint8_t ArialMT_Plain_10_PL[] PROGMEM = {
-0x0A, // Width: 10
-0x0D, // Height: 13
-0x20, // First char: 32
-0xE0, // Number of chars: 224
-// Jump Table:
-0xFF, 0xFF, 0x00, 0x03, // 32
-0x00, 0x00, 0x04, 0x03, // 33
-0x00, 0x04, 0x05, 0x04, // 34
-0x00, 0x09, 0x09, 0x06, // 35
-0x00, 0x12, 0x0A, 0x06, // 36
-0x00, 0x1C, 0x10, 0x09, // 37
-0x00, 0x2C, 0x0E, 0x08, // 38
-0x00, 0x3A, 0x01, 0x02, // 39
-0x00, 0x3B, 0x06, 0x04, // 40
-0x00, 0x41, 0x06, 0x04, // 41
-0x00, 0x47, 0x05, 0x04, // 42
-0x00, 0x4C, 0x09, 0x06, // 43
-0x00, 0x55, 0x04, 0x03, // 44
-0x00, 0x59, 0x03, 0x03, // 45
-0x00, 0x5C, 0x04, 0x03, // 46
-0x00, 0x60, 0x05, 0x04, // 47
-0x00, 0x65, 0x0A, 0x06, // 48
-0x00, 0x6F, 0x08, 0x05, // 49
-0x00, 0x77, 0x0A, 0x06, // 50
-0x00, 0x81, 0x0A, 0x06, // 51
-0x00, 0x8B, 0x0B, 0x07, // 52
-0x00, 0x96, 0x0A, 0x06, // 53
-0x00, 0xA0, 0x0A, 0x06, // 54
-0x00, 0xAA, 0x09, 0x06, // 55
-0x00, 0xB3, 0x0A, 0x06, // 56
-0x00, 0xBD, 0x0A, 0x06, // 57
-0x00, 0xC7, 0x04, 0x03, // 58
-0x00, 0xCB, 0x04, 0x03, // 59
-0x00, 0xCF, 0x0A, 0x06, // 60
-0x00, 0xD9, 0x09, 0x06, // 61
-0x00, 0xE2, 0x09, 0x06, // 62
-0x00, 0xEB, 0x0B, 0x07, // 63
-0x00, 0xF6, 0x14, 0x0B, // 64
-0x01, 0x0A, 0x0E, 0x08, // 65
-0x01, 0x18, 0x0C, 0x07, // 66
-0x01, 0x24, 0x0C, 0x07, // 67
-0x01, 0x30, 0x0B, 0x07, // 68
-0x01, 0x3B, 0x0C, 0x07, // 69
-0x01, 0x47, 0x09, 0x06, // 70
-0x01, 0x50, 0x0D, 0x08, // 71
-0x01, 0x5D, 0x0C, 0x07, // 72
-0x01, 0x69, 0x04, 0x03, // 73
-0x01, 0x6D, 0x08, 0x05, // 74
-0x01, 0x75, 0x0E, 0x08, // 75
-0x01, 0x83, 0x0C, 0x07, // 76
-0x01, 0x8F, 0x10, 0x09, // 77
-0x01, 0x9F, 0x0C, 0x07, // 78
-0x01, 0xAB, 0x0E, 0x08, // 79
-0x01, 0xB9, 0x0B, 0x07, // 80
-0x01, 0xC4, 0x0E, 0x08, // 81
-0x01, 0xD2, 0x0C, 0x07, // 82
-0x01, 0xDE, 0x0C, 0x07, // 83
-0x01, 0xEA, 0x0B, 0x07, // 84
-0x01, 0xF5, 0x0C, 0x07, // 85
-0x02, 0x01, 0x0D, 0x08, // 86
-0x02, 0x0E, 0x11, 0x0A, // 87
-0x02, 0x1F, 0x0E, 0x08, // 88
-0x02, 0x2D, 0x0D, 0x08, // 89
-0x02, 0x3A, 0x0C, 0x07, // 90
-0x02, 0x46, 0x06, 0x04, // 91
-0x02, 0x4C, 0x06, 0x04, // 92
-0x02, 0x52, 0x04, 0x03, // 93
-0x02, 0x56, 0x09, 0x06, // 94
-0x02, 0x5F, 0x0C, 0x07, // 95
-0x02, 0x6B, 0x03, 0x03, // 96
-0x02, 0x6E, 0x0A, 0x06, // 97
-0x02, 0x78, 0x0A, 0x06, // 98
-0x02, 0x82, 0x0A, 0x06, // 99
-0x02, 0x8C, 0x0A, 0x06, // 100
-0x02, 0x96, 0x0A, 0x06, // 101
-0x02, 0xA0, 0x05, 0x04, // 102
-0x02, 0xA5, 0x0A, 0x06, // 103
-0x02, 0xAF, 0x0A, 0x06, // 104
-0x02, 0xB9, 0x04, 0x03, // 105
-0x02, 0xBD, 0x04, 0x03, // 106
-0x02, 0xC1, 0x08, 0x05, // 107
-0x02, 0xC9, 0x04, 0x03, // 108
-0x02, 0xCD, 0x10, 0x09, // 109
-0x02, 0xDD, 0x0A, 0x06, // 110
-0x02, 0xE7, 0x0A, 0x06, // 111
-0x02, 0xF1, 0x0A, 0x06, // 112
-0x02, 0xFB, 0x0A, 0x06, // 113
-0x03, 0x05, 0x05, 0x04, // 114
-0x03, 0x0A, 0x08, 0x05, // 115
-0x03, 0x12, 0x06, 0x04, // 116
-0x03, 0x18, 0x0A, 0x06, // 117
-0x03, 0x22, 0x09, 0x06, // 118
-0x03, 0x2B, 0x0E, 0x08, // 119
-0x03, 0x39, 0x0A, 0x06, // 120
-0x03, 0x43, 0x09, 0x06, // 121
-0x03, 0x4C, 0x0A, 0x06, // 122
-0x03, 0x56, 0x06, 0x04, // 123
-0x03, 0x5C, 0x04, 0x03, // 124
-0x03, 0x60, 0x05, 0x04, // 125
-0x03, 0x65, 0x09, 0x06, // 126
-0xFF, 0xFF, 0x00, 0x0A, // 127
-0xFF, 0xFF, 0x00, 0x0A, // 128
-0x03, 0x6E, 0x0C, 0x07, // 129
-0x03, 0x7A, 0x05, 0x04, // 130
-0x03, 0x7F, 0x0C, 0x07, // 131
-0x03, 0x8B, 0x0E, 0x08, // 132
-0x03, 0x99, 0x0A, 0x06, // 133
-0x03, 0xA3, 0x0C, 0x07, // 134
-0x03, 0xAF, 0x0A, 0x06, // 135
-0x03, 0xB9, 0x0A, 0x06, // 136
-0x03, 0xC3, 0x0A, 0x06, // 137
-0xFF, 0xFF, 0x00, 0x0A, // 138
-0xFF, 0xFF, 0x00, 0x0A, // 139
-0xFF, 0xFF, 0x00, 0x0A, // 140
-0xFF, 0xFF, 0x00, 0x0A, // 141
-0xFF, 0xFF, 0x00, 0x0A, // 142
-0xFF, 0xFF, 0x00, 0x0A, // 143
-0xFF, 0xFF, 0x00, 0x0A, // 144
-0xFF, 0xFF, 0x00, 0x0A, // 145
-0xFF, 0xFF, 0x00, 0x0A, // 146
-0x03, 0xCD, 0x0E, 0x08, // 147
-0x03, 0xDB, 0x0A, 0x06, // 148
-0xFF, 0xFF, 0x00, 0x0A, // 149
-0xFF, 0xFF, 0x00, 0x0A, // 150
-0xFF, 0xFF, 0x00, 0x0A, // 151
-0x03, 0xE5, 0x0C, 0x07, // 152
-0x03, 0xF1, 0x0A, 0x06, // 153
-0x03, 0xFB, 0x0C, 0x07, // 154
-0x04, 0x07, 0x08, 0x05, // 155
-0xFF, 0xFF, 0x00, 0x0A, // 156
-0xFF, 0xFF, 0x00, 0x0A, // 157
-0xFF, 0xFF, 0x00, 0x0A, // 158
-0xFF, 0xFF, 0x00, 0x0A, // 159
-0xFF, 0xFF, 0x00, 0x0A, // 160
-0x04, 0x0F, 0x04, 0x03, // 161
-0x04, 0x13, 0x0A, 0x06, // 162
-0x04, 0x1D, 0x0C, 0x07, // 163
-0x04, 0x29, 0x0A, 0x06, // 164
-0x04, 0x33, 0x0A, 0x06, // 165
-0x04, 0x3D, 0x04, 0x03, // 166
-0x04, 0x41, 0x0A, 0x06, // 167
-0x04, 0x4B, 0x05, 0x04, // 168
-0x04, 0x50, 0x0D, 0x08, // 169
-0x04, 0x5D, 0x07, 0x05, // 170
-0x04, 0x64, 0x0A, 0x06, // 171
-0x04, 0x6E, 0x09, 0x06, // 172
-0x04, 0x77, 0x03, 0x03, // 173
-0x04, 0x7A, 0x0D, 0x08, // 174
-0x04, 0x87, 0x0B, 0x07, // 175
-0x04, 0x92, 0x07, 0x05, // 176
-0x04, 0x99, 0x0A, 0x06, // 177
-0x04, 0xA3, 0x05, 0x04, // 178
-0x04, 0xA8, 0x05, 0x04, // 179
-0x04, 0xAD, 0x05, 0x04, // 180
-0x04, 0xB2, 0x0A, 0x06, // 181
-0x04, 0xBC, 0x09, 0x06, // 182
-0x04, 0xC5, 0x03, 0x03, // 183
-0x04, 0xC8, 0x06, 0x04, // 184
-0x04, 0xCE, 0x0C, 0x07, // 185
-0x04, 0xDA, 0x07, 0x05, // 186
-0x04, 0xE1, 0x0C, 0x07, // 187
-0x04, 0xED, 0x0A, 0x06, // 188
-0x04, 0xF7, 0x10, 0x09, // 189
-0x05, 0x07, 0x10, 0x09, // 190
-0x05, 0x17, 0x0A, 0x06, // 191
-0x05, 0x21, 0x0E, 0x08, // 192
-0x05, 0x2F, 0x0E, 0x08, // 193
-0x05, 0x3D, 0x0E, 0x08, // 194
-0x05, 0x4B, 0x0E, 0x08, // 195
-0x05, 0x59, 0x0E, 0x08, // 196
-0x05, 0x67, 0x0E, 0x08, // 197
-0x05, 0x75, 0x12, 0x0A, // 198
-0x05, 0x87, 0x0C, 0x07, // 199
-0x05, 0x93, 0x0C, 0x07, // 200
-0x05, 0x9F, 0x0C, 0x07, // 201
-0x05, 0xAB, 0x0C, 0x07, // 202
-0x05, 0xB7, 0x0C, 0x07, // 203
-0x05, 0xC3, 0x05, 0x04, // 204
-0x05, 0xC8, 0x04, 0x03, // 205
-0x05, 0xCC, 0x04, 0x03, // 206
-0x05, 0xD0, 0x05, 0x04, // 207
-0x05, 0xD5, 0x0B, 0x07, // 208
-0x05, 0xE0, 0x0C, 0x07, // 209
-0x05, 0xEC, 0x0E, 0x08, // 210
-0x05, 0xFA, 0x0E, 0x08, // 211
-0x06, 0x08, 0x0E, 0x08, // 212
-0x06, 0x16, 0x0E, 0x08, // 213
-0x06, 0x24, 0x0E, 0x08, // 214
-0x06, 0x32, 0x0A, 0x06, // 215
-0x06, 0x3C, 0x0D, 0x08, // 216
-0x06, 0x49, 0x0C, 0x07, // 217
-0x06, 0x55, 0x0C, 0x07, // 218
-0x06, 0x61, 0x0C, 0x07, // 219
-0x06, 0x6D, 0x0C, 0x07, // 220
-0x06, 0x79, 0x0D, 0x08, // 221
-0x06, 0x86, 0x0B, 0x07, // 222
-0x06, 0x91, 0x0C, 0x07, // 223
-0x06, 0x9D, 0x0A, 0x06, // 224
-0x06, 0xA7, 0x0A, 0x06, // 225
-0x06, 0xB1, 0x0A, 0x06, // 226
-0x06, 0xBB, 0x0A, 0x06, // 227
-0x06, 0xC5, 0x0A, 0x06, // 228
-0x06, 0xCF, 0x0A, 0x06, // 229
-0x06, 0xD9, 0x10, 0x09, // 230
-0x06, 0xE9, 0x0A, 0x06, // 231
-0x06, 0xF3, 0x0A, 0x06, // 232
-0x06, 0xFD, 0x0A, 0x06, // 233
-0x07, 0x07, 0x0A, 0x06, // 234
-0x07, 0x11, 0x0A, 0x06, // 235
-0x07, 0x1B, 0x05, 0x04, // 236
-0x07, 0x20, 0x04, 0x03, // 237
-0x07, 0x24, 0x05, 0x04, // 238
-0x07, 0x29, 0x05, 0x04, // 239
-0x07, 0x2E, 0x0A, 0x06, // 240
-0x07, 0x38, 0x0A, 0x06, // 241
-0x07, 0x42, 0x0A, 0x06, // 242
-0x07, 0x4C, 0x0A, 0x06, // 243
-0x07, 0x56, 0x0A, 0x06, // 244
-0x07, 0x60, 0x0A, 0x06, // 245
-0x07, 0x6A, 0x0A, 0x06, // 246
-0x07, 0x74, 0x09, 0x06, // 247
-0x07, 0x7D, 0x0A, 0x06, // 248
-0x07, 0x87, 0x0A, 0x06, // 249
-0x07, 0x91, 0x0A, 0x06, // 250
-0x07, 0x9B, 0x0A, 0x06, // 251
-0x07, 0xA5, 0x0A, 0x06, // 252
-0x07, 0xAF, 0x09, 0x06, // 253
-0x07, 0xB8, 0x0A, 0x06, // 254
-0x07, 0xC2, 0x09, 0x06, // 255
-// Font Data:
-0x00, 0x00, 0xF8, 0x02, // 33
-0x38, 0x00, 0x00, 0x00, 0x38, // 34
-0xA0, 0x03, 0xE0, 0x00, 0xB8, 0x03, 0xE0, 0x00, 0xB8, // 35
-0x30, 0x01, 0x28, 0x02, 0xF8, 0x07, 0x48, 0x02, 0x90, 0x01, // 36
-0x00, 0x00, 0x30, 0x00, 0x48, 0x00, 0x30, 0x03, 0xC0, 0x00, 0xB0, 0x01, 0x48, 0x02, 0x80, 0x01, // 37
-0x80, 0x01, 0x50, 0x02, 0x68, 0x02, 0xA8, 0x02, 0x18, 0x01, 0x80, 0x03, 0x80, 0x02, // 38
-0x38, // 39
-0xE0, 0x03, 0x10, 0x04, 0x08, 0x08, // 40
-0x08, 0x08, 0x10, 0x04, 0xE0, 0x03, // 41
-0x28, 0x00, 0x18, 0x00, 0x28, // 42
-0x40, 0x00, 0x40, 0x00, 0xF0, 0x01, 0x40, 0x00, 0x40, // 43
-0x00, 0x00, 0x00, 0x06, // 44
-0x80, 0x00, 0x80, // 45
-0x00, 0x00, 0x00, 0x02, // 46
-0x00, 0x03, 0xE0, 0x00, 0x18, // 47
-0xF0, 0x01, 0x08, 0x02, 0x08, 0x02, 0x08, 0x02, 0xF0, 0x01, // 48
-0x00, 0x00, 0x20, 0x00, 0x10, 0x00, 0xF8, 0x03, // 49
-0x10, 0x02, 0x08, 0x03, 0x88, 0x02, 0x48, 0x02, 0x30, 0x02, // 50
-0x10, 0x01, 0x08, 0x02, 0x48, 0x02, 0x48, 0x02, 0xB0, 0x01, // 51
-0xC0, 0x00, 0xA0, 0x00, 0x90, 0x00, 0x88, 0x00, 0xF8, 0x03, 0x80, // 52
-0x60, 0x01, 0x38, 0x02, 0x28, 0x02, 0x28, 0x02, 0xC8, 0x01, // 53
-0xF0, 0x01, 0x28, 0x02, 0x28, 0x02, 0x28, 0x02, 0xD0, 0x01, // 54
-0x08, 0x00, 0x08, 0x03, 0xC8, 0x00, 0x38, 0x00, 0x08, // 55
-0xB0, 0x01, 0x48, 0x02, 0x48, 0x02, 0x48, 0x02, 0xB0, 0x01, // 56
-0x70, 0x01, 0x88, 0x02, 0x88, 0x02, 0x88, 0x02, 0xF0, 0x01, // 57
-0x00, 0x00, 0x20, 0x02, // 58
-0x00, 0x00, 0x20, 0x06, // 59
-0x00, 0x00, 0x40, 0x00, 0xA0, 0x00, 0xA0, 0x00, 0x10, 0x01, // 60
-0xA0, 0x00, 0xA0, 0x00, 0xA0, 0x00, 0xA0, 0x00, 0xA0, // 61
-0x00, 0x00, 0x10, 0x01, 0xA0, 0x00, 0xA0, 0x00, 0x40, // 62
-0x10, 0x00, 0x08, 0x00, 0x08, 0x00, 0xC8, 0x02, 0x48, 0x00, 0x30, // 63
-0x00, 0x00, 0xC0, 0x03, 0x30, 0x04, 0xD0, 0x09, 0x28, 0x0A, 0x28, 0x0A, 0xC8, 0x0B, 0x68, 0x0A, 0x10, 0x05, 0xE0, 0x04, // 64
-0x00, 0x02, 0xC0, 0x01, 0xB0, 0x00, 0x88, 0x00, 0xB0, 0x00, 0xC0, 0x01, 0x00, 0x02, // 65
-0x00, 0x00, 0xF8, 0x03, 0x48, 0x02, 0x48, 0x02, 0x48, 0x02, 0xF0, 0x01, // 66
-0x00, 0x00, 0xF0, 0x01, 0x08, 0x02, 0x08, 0x02, 0x08, 0x02, 0x10, 0x01, // 67
-0x00, 0x00, 0xF8, 0x03, 0x08, 0x02, 0x08, 0x02, 0x10, 0x01, 0xE0, // 68
-0x00, 0x00, 0xF8, 0x03, 0x48, 0x02, 0x48, 0x02, 0x48, 0x02, 0x48, 0x02, // 69
-0x00, 0x00, 0xF8, 0x03, 0x48, 0x00, 0x48, 0x00, 0x08, // 70
-0x00, 0x00, 0xE0, 0x00, 0x10, 0x01, 0x08, 0x02, 0x48, 0x02, 0x50, 0x01, 0xC0, // 71
-0x00, 0x00, 0xF8, 0x03, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0xF8, 0x03, // 72
-0x00, 0x00, 0xF8, 0x03, // 73
-0x00, 0x03, 0x00, 0x02, 0x00, 0x02, 0xF8, 0x01, // 74
-0x00, 0x00, 0xF8, 0x03, 0x80, 0x00, 0x60, 0x00, 0x90, 0x00, 0x08, 0x01, 0x00, 0x02, // 75
-0x00, 0x00, 0xF8, 0x03, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, // 76
-0x00, 0x00, 0xF8, 0x03, 0x30, 0x00, 0xC0, 0x01, 0x00, 0x02, 0xC0, 0x01, 0x30, 0x00, 0xF8, 0x03, // 77
-0x00, 0x00, 0xF8, 0x03, 0x30, 0x00, 0x40, 0x00, 0x80, 0x01, 0xF8, 0x03, // 78
-0x00, 0x00, 0xF0, 0x01, 0x08, 0x02, 0x08, 0x02, 0x08, 0x02, 0x08, 0x02, 0xF0, 0x01, // 79
-0x00, 0x00, 0xF8, 0x03, 0x48, 0x00, 0x48, 0x00, 0x48, 0x00, 0x30, // 80
-0x00, 0x00, 0xF0, 0x01, 0x08, 0x02, 0x08, 0x02, 0x08, 0x03, 0x08, 0x03, 0xF0, 0x02, // 81
-0x00, 0x00, 0xF8, 0x03, 0x48, 0x00, 0x48, 0x00, 0xC8, 0x00, 0x30, 0x03, // 82
-0x00, 0x00, 0x30, 0x01, 0x48, 0x02, 0x48, 0x02, 0x48, 0x02, 0x90, 0x01, // 83
-0x00, 0x00, 0x08, 0x00, 0x08, 0x00, 0xF8, 0x03, 0x08, 0x00, 0x08, // 84
-0x00, 0x00, 0xF8, 0x01, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0xF8, 0x01, // 85
-0x08, 0x00, 0x70, 0x00, 0x80, 0x01, 0x00, 0x02, 0x80, 0x01, 0x70, 0x00, 0x08, // 86
-0x18, 0x00, 0xE0, 0x01, 0x00, 0x02, 0xF0, 0x01, 0x08, 0x00, 0xF0, 0x01, 0x00, 0x02, 0xE0, 0x01, 0x18, // 87
-0x00, 0x02, 0x08, 0x01, 0x90, 0x00, 0x60, 0x00, 0x90, 0x00, 0x08, 0x01, 0x00, 0x02, // 88
-0x08, 0x00, 0x10, 0x00, 0x20, 0x00, 0xC0, 0x03, 0x20, 0x00, 0x10, 0x00, 0x08, // 89
-0x08, 0x03, 0x88, 0x02, 0xC8, 0x02, 0x68, 0x02, 0x38, 0x02, 0x18, 0x02, // 90
-0x00, 0x00, 0xF8, 0x0F, 0x08, 0x08, // 91
-0x18, 0x00, 0xE0, 0x00, 0x00, 0x03, // 92
-0x08, 0x08, 0xF8, 0x0F, // 93
-0x40, 0x00, 0x30, 0x00, 0x08, 0x00, 0x30, 0x00, 0x40, // 94
-0x00, 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, 0x08, // 95
-0x08, 0x00, 0x10, // 96
-0x00, 0x00, 0x00, 0x03, 0xA0, 0x02, 0xA0, 0x02, 0xE0, 0x03, // 97
-0x00, 0x00, 0xF8, 0x03, 0x20, 0x02, 0x20, 0x02, 0xC0, 0x01, // 98
-0x00, 0x00, 0xC0, 0x01, 0x20, 0x02, 0x20, 0x02, 0x40, 0x01, // 99
-0x00, 0x00, 0xC0, 0x01, 0x20, 0x02, 0x20, 0x02, 0xF8, 0x03, // 100
-0x00, 0x00, 0xC0, 0x01, 0xA0, 0x02, 0xA0, 0x02, 0xC0, 0x02, // 101
-0x20, 0x00, 0xF0, 0x03, 0x28, // 102
-0x00, 0x00, 0xC0, 0x05, 0x20, 0x0A, 0x20, 0x0A, 0xE0, 0x07, // 103
-0x00, 0x00, 0xF8, 0x03, 0x20, 0x00, 0x20, 0x00, 0xC0, 0x03, // 104
-0x00, 0x00, 0xE8, 0x03, // 105
-0x00, 0x08, 0xE8, 0x07, // 106
-0xF8, 0x03, 0x80, 0x00, 0xC0, 0x01, 0x20, 0x02, // 107
-0x00, 0x00, 0xF8, 0x03, // 108
-0x00, 0x00, 0xE0, 0x03, 0x20, 0x00, 0x20, 0x00, 0xE0, 0x03, 0x20, 0x00, 0x20, 0x00, 0xC0, 0x03, // 109
-0x00, 0x00, 0xE0, 0x03, 0x20, 0x00, 0x20, 0x00, 0xC0, 0x03, // 110
-0x00, 0x00, 0xC0, 0x01, 0x20, 0x02, 0x20, 0x02, 0xC0, 0x01, // 111
-0x00, 0x00, 0xE0, 0x0F, 0x20, 0x02, 0x20, 0x02, 0xC0, 0x01, // 112
-0x00, 0x00, 0xC0, 0x01, 0x20, 0x02, 0x20, 0x02, 0xE0, 0x0F, // 113
-0x00, 0x00, 0xE0, 0x03, 0x20, // 114
-0x40, 0x02, 0xA0, 0x02, 0xA0, 0x02, 0x20, 0x01, // 115
-0x20, 0x00, 0xF8, 0x03, 0x20, 0x02, // 116
-0x00, 0x00, 0xE0, 0x01, 0x00, 0x02, 0x00, 0x02, 0xE0, 0x03, // 117
-0x20, 0x00, 0xC0, 0x01, 0x00, 0x02, 0xC0, 0x01, 0x20, // 118
-0xE0, 0x01, 0x00, 0x02, 0xC0, 0x01, 0x20, 0x00, 0xC0, 0x01, 0x00, 0x02, 0xE0, 0x01, // 119
-0x20, 0x02, 0x40, 0x01, 0x80, 0x00, 0x40, 0x01, 0x20, 0x02, // 120
-0x20, 0x00, 0xC0, 0x09, 0x00, 0x06, 0xC0, 0x01, 0x20, // 121
-0x20, 0x02, 0x20, 0x03, 0xA0, 0x02, 0x60, 0x02, 0x20, 0x02, // 122
-0x80, 0x00, 0x78, 0x0F, 0x08, 0x08, // 123
-0x00, 0x00, 0xF8, 0x0F, // 124
-0x08, 0x08, 0x78, 0x0F, 0x80, // 125
-0xC0, 0x00, 0x40, 0x00, 0xC0, 0x00, 0x80, 0x00, 0xC0, // 126
-0x00, 0x00, 0xF8, 0x03, 0x40, 0x02, 0x20, 0x02, 0x00, 0x02, 0x00, 0x02, // 129
-0x40, 0x00, 0xF8, 0x03, 0x20, // 130
-0x00, 0x00, 0xF8, 0x03, 0x30, 0x00, 0x44, 0x00, 0x82, 0x01, 0xF8, 0x03, // 131
-0x00, 0x02, 0xC0, 0x01, 0xB0, 0x00, 0x88, 0x00, 0xB0, 0x00, 0xC0, 0x0D, 0x00, 0x0A, // 132
-0x00, 0x00, 0x00, 0x03, 0xA0, 0x02, 0xA0, 0x0E, 0xE0, 0x0B, // 133
-0x00, 0x00, 0xF0, 0x01, 0x08, 0x02, 0x0A, 0x02, 0x09, 0x02, 0x10, 0x01, // 134
-0x00, 0x00, 0xC0, 0x01, 0x20, 0x02, 0x28, 0x02, 0x44, 0x01, // 135
-0x00, 0x00, 0xE0, 0x03, 0x20, 0x00, 0x28, 0x00, 0xC4, 0x03, // 136
-0x20, 0x02, 0x20, 0x03, 0xA8, 0x02, 0x64, 0x02, 0x20, 0x02, // 137
-0x00, 0x00, 0xF0, 0x01, 0x08, 0x02, 0x08, 0x02, 0x0A, 0x02, 0x09, 0x02, 0xF0, 0x01, // 147
-0x00, 0x00, 0xC0, 0x01, 0x20, 0x02, 0x28, 0x02, 0xC4, 0x01, // 148
-0x00, 0x00, 0xF8, 0x03, 0x48, 0x02, 0x48, 0x0E, 0x48, 0x0A, 0x48, 0x02, // 152
-0x00, 0x00, 0xC0, 0x01, 0xA0, 0x02, 0xA0, 0x0E, 0xC0, 0x0A, // 153
-0x00, 0x00, 0x30, 0x01, 0x48, 0x02, 0x4A, 0x02, 0x49, 0x02, 0x90, 0x01, // 154
-0x40, 0x02, 0xA0, 0x02, 0xA8, 0x02, 0x24, 0x01, // 155
-0x00, 0x00, 0xA0, 0x0F, // 161
-0x00, 0x00, 0xC0, 0x01, 0xA0, 0x0F, 0x78, 0x02, 0x40, 0x01, // 162
-0x40, 0x02, 0x70, 0x03, 0xC8, 0x02, 0x48, 0x02, 0x08, 0x02, 0x10, 0x02, // 163
-0x00, 0x00, 0xE0, 0x01, 0x20, 0x01, 0x20, 0x01, 0xE0, 0x01, // 164
-0x48, 0x01, 0x70, 0x01, 0xC0, 0x03, 0x70, 0x01, 0x48, 0x01, // 165
-0x00, 0x00, 0x38, 0x0F, // 166
-0xD0, 0x04, 0x28, 0x09, 0x48, 0x09, 0x48, 0x0A, 0x90, 0x05, // 167
-0x08, 0x00, 0x00, 0x00, 0x08, // 168
-0xE0, 0x00, 0x10, 0x01, 0x48, 0x02, 0xA8, 0x02, 0xA8, 0x02, 0x10, 0x01, 0xE0, // 169
-0x68, 0x00, 0x68, 0x00, 0x68, 0x00, 0x78, // 170
-0x00, 0x00, 0x80, 0x01, 0x40, 0x02, 0x80, 0x01, 0x40, 0x02, // 171
-0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0xE0, // 172
-0x80, 0x00, 0x80, // 173
-0xE0, 0x00, 0x10, 0x01, 0xE8, 0x02, 0x68, 0x02, 0xC8, 0x02, 0x10, 0x01, 0xE0, // 174
-0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, // 175
-0x00, 0x00, 0x38, 0x00, 0x28, 0x00, 0x38, // 176
-0x40, 0x02, 0x40, 0x02, 0xF0, 0x03, 0x40, 0x02, 0x40, 0x02, // 177
-0x48, 0x00, 0x68, 0x00, 0x58, // 178
-0x48, 0x00, 0x58, 0x00, 0x68, // 179
-0x00, 0x00, 0x10, 0x00, 0x08, // 180
-0x00, 0x00, 0xE0, 0x0F, 0x00, 0x02, 0x00, 0x02, 0xE0, 0x03, // 181
-0x70, 0x00, 0xF8, 0x0F, 0x08, 0x00, 0xF8, 0x0F, 0x08, // 182
-0x00, 0x00, 0x40, // 183
-0x00, 0x00, 0x00, 0x14, 0x00, 0x18, // 184
-0x08, 0x03, 0x88, 0x02, 0xCA, 0x02, 0x69, 0x02, 0x38, 0x02, 0x18, 0x02, // 185
-0x30, 0x00, 0x48, 0x00, 0x48, 0x00, 0x30, // 186
-0x08, 0x03, 0x88, 0x02, 0xC8, 0x02, 0x6A, 0x02, 0x38, 0x02, 0x18, 0x02, // 187
-0x20, 0x02, 0x20, 0x03, 0xA8, 0x02, 0x60, 0x02, 0x20, 0x02, // 188
-0x00, 0x00, 0x10, 0x02, 0x78, 0x01, 0x80, 0x00, 0x60, 0x00, 0x50, 0x02, 0x48, 0x03, 0xC0, 0x02, // 189
-0x48, 0x00, 0x58, 0x00, 0x68, 0x03, 0x80, 0x00, 0x60, 0x01, 0x90, 0x01, 0xC8, 0x03, 0x00, 0x01, // 190
-0x00, 0x00, 0x00, 0x06, 0x00, 0x09, 0xA0, 0x09, 0x00, 0x04, // 191
-0x00, 0x02, 0xC0, 0x01, 0xB0, 0x00, 0x89, 0x00, 0xB2, 0x00, 0xC0, 0x01, 0x00, 0x02, // 192
-0x00, 0x02, 0xC0, 0x01, 0xB0, 0x00, 0x8A, 0x00, 0xB1, 0x00, 0xC0, 0x01, 0x00, 0x02, // 193
-0x00, 0x02, 0xC0, 0x01, 0xB2, 0x00, 0x89, 0x00, 0xB2, 0x00, 0xC0, 0x01, 0x00, 0x02, // 194
-0x00, 0x02, 0xC2, 0x01, 0xB1, 0x00, 0x8A, 0x00, 0xB1, 0x00, 0xC0, 0x01, 0x00, 0x02, // 195
-0x00, 0x02, 0xC0, 0x01, 0xB2, 0x00, 0x88, 0x00, 0xB2, 0x00, 0xC0, 0x01, 0x00, 0x02, // 196
-0x00, 0x02, 0xC0, 0x01, 0xBE, 0x00, 0x8A, 0x00, 0xBE, 0x00, 0xC0, 0x01, 0x00, 0x02, // 197
-0x00, 0x03, 0xC0, 0x00, 0xE0, 0x00, 0x98, 0x00, 0x88, 0x00, 0xF8, 0x03, 0x48, 0x02, 0x48, 0x02, 0x48, 0x02, // 198
-0x00, 0x00, 0xF0, 0x01, 0x08, 0x02, 0x08, 0x16, 0x08, 0x1A, 0x10, 0x01, // 199
-0x00, 0x00, 0xF8, 0x03, 0x49, 0x02, 0x4A, 0x02, 0x48, 0x02, 0x48, 0x02, // 200
-0x00, 0x00, 0xF8, 0x03, 0x48, 0x02, 0x4A, 0x02, 0x49, 0x02, 0x48, 0x02, // 201
-0x00, 0x00, 0xFA, 0x03, 0x49, 0x02, 0x4A, 0x02, 0x48, 0x02, 0x48, 0x02, // 202
-0x00, 0x00, 0xF8, 0x03, 0x4A, 0x02, 0x48, 0x02, 0x4A, 0x02, 0x48, 0x02, // 203
-0x00, 0x00, 0xF9, 0x03, 0x02, // 204
-0x02, 0x00, 0xF9, 0x03, // 205
-0x01, 0x00, 0xFA, 0x03, // 206
-0x02, 0x00, 0xF8, 0x03, 0x02, // 207
-0x40, 0x00, 0xF8, 0x03, 0x48, 0x02, 0x48, 0x02, 0x10, 0x01, 0xE0, // 208
-0x00, 0x00, 0xFA, 0x03, 0x31, 0x00, 0x42, 0x00, 0x81, 0x01, 0xF8, 0x03, // 209
-0x00, 0x00, 0xF0, 0x01, 0x08, 0x02, 0x09, 0x02, 0x0A, 0x02, 0x08, 0x02, 0xF0, 0x01, // 210
-0x00, 0x00, 0xF0, 0x01, 0x08, 0x02, 0x0A, 0x02, 0x09, 0x02, 0x08, 0x02, 0xF0, 0x01, // 211
-0x00, 0x00, 0xF0, 0x01, 0x08, 0x02, 0x0A, 0x02, 0x09, 0x02, 0x0A, 0x02, 0xF0, 0x01, // 212
-0x00, 0x00, 0xF0, 0x01, 0x0A, 0x02, 0x09, 0x02, 0x0A, 0x02, 0x09, 0x02, 0xF0, 0x01, // 213
-0x00, 0x00, 0xF0, 0x01, 0x0A, 0x02, 0x08, 0x02, 0x0A, 0x02, 0x08, 0x02, 0xF0, 0x01, // 214
-0x10, 0x01, 0xA0, 0x00, 0xE0, 0x00, 0xA0, 0x00, 0x10, 0x01, // 215
-0x00, 0x00, 0xF0, 0x02, 0x08, 0x03, 0xC8, 0x02, 0x28, 0x02, 0x18, 0x03, 0xE8, // 216
-0x00, 0x00, 0xF8, 0x01, 0x01, 0x02, 0x02, 0x02, 0x00, 0x02, 0xF8, 0x01, // 217
-0x00, 0x00, 0xF8, 0x01, 0x02, 0x02, 0x01, 0x02, 0x00, 0x02, 0xF8, 0x01, // 218
-0x00, 0x00, 0xF8, 0x01, 0x02, 0x02, 0x01, 0x02, 0x02, 0x02, 0xF8, 0x01, // 219
-0x00, 0x00, 0xF8, 0x01, 0x02, 0x02, 0x00, 0x02, 0x02, 0x02, 0xF8, 0x01, // 220
-0x08, 0x00, 0x10, 0x00, 0x20, 0x00, 0xC2, 0x03, 0x21, 0x00, 0x10, 0x00, 0x08, // 221
-0x00, 0x00, 0xF8, 0x03, 0x10, 0x01, 0x10, 0x01, 0x10, 0x01, 0xE0, // 222
-0x00, 0x00, 0xF0, 0x03, 0x08, 0x01, 0x48, 0x02, 0xB0, 0x02, 0x80, 0x01, // 223
-0x00, 0x00, 0x00, 0x03, 0xA4, 0x02, 0xA8, 0x02, 0xE0, 0x03, // 224
-0x00, 0x00, 0x00, 0x03, 0xA8, 0x02, 0xA4, 0x02, 0xE0, 0x03, // 225
-0x00, 0x00, 0x00, 0x03, 0xA8, 0x02, 0xA4, 0x02, 0xE8, 0x03, // 226
-0x00, 0x00, 0x08, 0x03, 0xA4, 0x02, 0xA8, 0x02, 0xE4, 0x03, // 227
-0x00, 0x00, 0x00, 0x03, 0xA8, 0x02, 0xA0, 0x02, 0xE8, 0x03, // 228
-0x00, 0x00, 0x00, 0x03, 0xAE, 0x02, 0xAA, 0x02, 0xEE, 0x03, // 229
-0x00, 0x00, 0x40, 0x03, 0xA0, 0x02, 0xA0, 0x02, 0xC0, 0x01, 0xA0, 0x02, 0xA0, 0x02, 0xC0, 0x02, // 230
-0x00, 0x00, 0xC0, 0x01, 0x20, 0x16, 0x20, 0x1A, 0x40, 0x01, // 231
-0x00, 0x00, 0xC0, 0x01, 0xA4, 0x02, 0xA8, 0x02, 0xC0, 0x02, // 232
-0x00, 0x00, 0xC0, 0x01, 0xA8, 0x02, 0xA4, 0x02, 0xC0, 0x02, // 233
-0x00, 0x00, 0xC0, 0x01, 0xA8, 0x02, 0xA4, 0x02, 0xC8, 0x02, // 234
-0x00, 0x00, 0xC0, 0x01, 0xA8, 0x02, 0xA0, 0x02, 0xC8, 0x02, // 235
-0x00, 0x00, 0xE4, 0x03, 0x08, // 236
-0x08, 0x00, 0xE4, 0x03, // 237
-0x08, 0x00, 0xE4, 0x03, 0x08, // 238
-0x08, 0x00, 0xE0, 0x03, 0x08, // 239
-0x00, 0x00, 0xC0, 0x01, 0x28, 0x02, 0x38, 0x02, 0xE0, 0x01, // 240
-0x00, 0x00, 0xE8, 0x03, 0x24, 0x00, 0x28, 0x00, 0xC4, 0x03, // 241
-0x00, 0x00, 0xC0, 0x01, 0x24, 0x02, 0x28, 0x02, 0xC0, 0x01, // 242
-0x00, 0x00, 0xC0, 0x01, 0x28, 0x02, 0x24, 0x02, 0xC0, 0x01, // 243
-0x00, 0x00, 0xC0, 0x01, 0x28, 0x02, 0x24, 0x02, 0xC8, 0x01, // 244
-0x00, 0x00, 0xC8, 0x01, 0x24, 0x02, 0x28, 0x02, 0xC4, 0x01, // 245
-0x00, 0x00, 0xC0, 0x01, 0x28, 0x02, 0x20, 0x02, 0xC8, 0x01, // 246
-0x40, 0x00, 0x40, 0x00, 0x50, 0x01, 0x40, 0x00, 0x40, // 247
-0x00, 0x00, 0xC0, 0x02, 0xA0, 0x03, 0x60, 0x02, 0xA0, 0x01, // 248
-0x00, 0x00, 0xE0, 0x01, 0x04, 0x02, 0x08, 0x02, 0xE0, 0x03, // 249
-0x00, 0x00, 0xE0, 0x01, 0x08, 0x02, 0x04, 0x02, 0xE0, 0x03, // 250
-0x00, 0x00, 0xE8, 0x01, 0x04, 0x02, 0x08, 0x02, 0xE0, 0x03, // 251
-0x00, 0x00, 0xE0, 0x01, 0x08, 0x02, 0x00, 0x02, 0xE8, 0x03, // 252
-0x20, 0x00, 0xC0, 0x09, 0x08, 0x06, 0xC4, 0x01, 0x20, // 253
-0x00, 0x00, 0xF8, 0x0F, 0x20, 0x02, 0x20, 0x02, 0xC0, 0x01, // 254
-0x20, 0x00, 0xC8, 0x09, 0x00, 0x06, 0xC8, 0x01, 0x20, // 255
+ 0x0A, // Width: 10
+ 0x0D, // Height: 13
+ 0x20, // First char: 32
+ 0xE0, // Number of chars: 224
+ // Jump Table:
+ 0xFF, 0xFF, 0x00, 0x03, // 32
+ 0x00, 0x00, 0x04, 0x03, // 33
+ 0x00, 0x04, 0x05, 0x04, // 34
+ 0x00, 0x09, 0x09, 0x06, // 35
+ 0x00, 0x12, 0x0A, 0x06, // 36
+ 0x00, 0x1C, 0x10, 0x09, // 37
+ 0x00, 0x2C, 0x0E, 0x08, // 38
+ 0x00, 0x3A, 0x01, 0x02, // 39
+ 0x00, 0x3B, 0x06, 0x04, // 40
+ 0x00, 0x41, 0x06, 0x04, // 41
+ 0x00, 0x47, 0x05, 0x04, // 42
+ 0x00, 0x4C, 0x09, 0x06, // 43
+ 0x00, 0x55, 0x04, 0x03, // 44
+ 0x00, 0x59, 0x03, 0x03, // 45
+ 0x00, 0x5C, 0x04, 0x03, // 46
+ 0x00, 0x60, 0x05, 0x04, // 47
+ 0x00, 0x65, 0x0A, 0x06, // 48
+ 0x00, 0x6F, 0x08, 0x05, // 49
+ 0x00, 0x77, 0x0A, 0x06, // 50
+ 0x00, 0x81, 0x0A, 0x06, // 51
+ 0x00, 0x8B, 0x0B, 0x07, // 52
+ 0x00, 0x96, 0x0A, 0x06, // 53
+ 0x00, 0xA0, 0x0A, 0x06, // 54
+ 0x00, 0xAA, 0x09, 0x06, // 55
+ 0x00, 0xB3, 0x0A, 0x06, // 56
+ 0x00, 0xBD, 0x0A, 0x06, // 57
+ 0x00, 0xC7, 0x04, 0x03, // 58
+ 0x00, 0xCB, 0x04, 0x03, // 59
+ 0x00, 0xCF, 0x0A, 0x06, // 60
+ 0x00, 0xD9, 0x09, 0x06, // 61
+ 0x00, 0xE2, 0x09, 0x06, // 62
+ 0x00, 0xEB, 0x0B, 0x07, // 63
+ 0x00, 0xF6, 0x14, 0x0B, // 64
+ 0x01, 0x0A, 0x0E, 0x08, // 65
+ 0x01, 0x18, 0x0C, 0x07, // 66
+ 0x01, 0x24, 0x0C, 0x07, // 67
+ 0x01, 0x30, 0x0B, 0x07, // 68
+ 0x01, 0x3B, 0x0C, 0x07, // 69
+ 0x01, 0x47, 0x09, 0x06, // 70
+ 0x01, 0x50, 0x0D, 0x08, // 71
+ 0x01, 0x5D, 0x0C, 0x07, // 72
+ 0x01, 0x69, 0x04, 0x03, // 73
+ 0x01, 0x6D, 0x08, 0x05, // 74
+ 0x01, 0x75, 0x0E, 0x08, // 75
+ 0x01, 0x83, 0x0C, 0x07, // 76
+ 0x01, 0x8F, 0x10, 0x09, // 77
+ 0x01, 0x9F, 0x0C, 0x07, // 78
+ 0x01, 0xAB, 0x0E, 0x08, // 79
+ 0x01, 0xB9, 0x0B, 0x07, // 80
+ 0x01, 0xC4, 0x0E, 0x08, // 81
+ 0x01, 0xD2, 0x0C, 0x07, // 82
+ 0x01, 0xDE, 0x0C, 0x07, // 83
+ 0x01, 0xEA, 0x0B, 0x07, // 84
+ 0x01, 0xF5, 0x0C, 0x07, // 85
+ 0x02, 0x01, 0x0D, 0x08, // 86
+ 0x02, 0x0E, 0x11, 0x0A, // 87
+ 0x02, 0x1F, 0x0E, 0x08, // 88
+ 0x02, 0x2D, 0x0D, 0x08, // 89
+ 0x02, 0x3A, 0x0C, 0x07, // 90
+ 0x02, 0x46, 0x06, 0x04, // 91
+ 0x02, 0x4C, 0x06, 0x04, // 92
+ 0x02, 0x52, 0x04, 0x03, // 93
+ 0x02, 0x56, 0x09, 0x06, // 94
+ 0x02, 0x5F, 0x0C, 0x07, // 95
+ 0x02, 0x6B, 0x03, 0x03, // 96
+ 0x02, 0x6E, 0x0A, 0x06, // 97
+ 0x02, 0x78, 0x0A, 0x06, // 98
+ 0x02, 0x82, 0x0A, 0x06, // 99
+ 0x02, 0x8C, 0x0A, 0x06, // 100
+ 0x02, 0x96, 0x0A, 0x06, // 101
+ 0x02, 0xA0, 0x05, 0x04, // 102
+ 0x02, 0xA5, 0x0A, 0x06, // 103
+ 0x02, 0xAF, 0x0A, 0x06, // 104
+ 0x02, 0xB9, 0x04, 0x03, // 105
+ 0x02, 0xBD, 0x04, 0x03, // 106
+ 0x02, 0xC1, 0x08, 0x05, // 107
+ 0x02, 0xC9, 0x04, 0x03, // 108
+ 0x02, 0xCD, 0x10, 0x09, // 109
+ 0x02, 0xDD, 0x0A, 0x06, // 110
+ 0x02, 0xE7, 0x0A, 0x06, // 111
+ 0x02, 0xF1, 0x0A, 0x06, // 112
+ 0x02, 0xFB, 0x0A, 0x06, // 113
+ 0x03, 0x05, 0x05, 0x04, // 114
+ 0x03, 0x0A, 0x08, 0x05, // 115
+ 0x03, 0x12, 0x06, 0x04, // 116
+ 0x03, 0x18, 0x0A, 0x06, // 117
+ 0x03, 0x22, 0x09, 0x06, // 118
+ 0x03, 0x2B, 0x0E, 0x08, // 119
+ 0x03, 0x39, 0x0A, 0x06, // 120
+ 0x03, 0x43, 0x09, 0x06, // 121
+ 0x03, 0x4C, 0x0A, 0x06, // 122
+ 0x03, 0x56, 0x06, 0x04, // 123
+ 0x03, 0x5C, 0x04, 0x03, // 124
+ 0x03, 0x60, 0x05, 0x04, // 125
+ 0x03, 0x65, 0x09, 0x06, // 126
+ 0xFF, 0xFF, 0x00, 0x0A, // 127
+ 0xFF, 0xFF, 0x00, 0x0A, // 128
+ 0x03, 0x6E, 0x0C, 0x07, // 129
+ 0x03, 0x7A, 0x05, 0x04, // 130
+ 0x03, 0x7F, 0x0C, 0x07, // 131
+ 0x03, 0x8B, 0x0E, 0x08, // 132
+ 0x03, 0x99, 0x0A, 0x06, // 133
+ 0x03, 0xA3, 0x0C, 0x07, // 134
+ 0x03, 0xAF, 0x0A, 0x06, // 135
+ 0x03, 0xB9, 0x0A, 0x06, // 136
+ 0x03, 0xC3, 0x0A, 0x06, // 137
+ 0xFF, 0xFF, 0x00, 0x0A, // 138
+ 0xFF, 0xFF, 0x00, 0x0A, // 139
+ 0xFF, 0xFF, 0x00, 0x0A, // 140
+ 0xFF, 0xFF, 0x00, 0x0A, // 141
+ 0xFF, 0xFF, 0x00, 0x0A, // 142
+ 0xFF, 0xFF, 0x00, 0x0A, // 143
+ 0xFF, 0xFF, 0x00, 0x0A, // 144
+ 0xFF, 0xFF, 0x00, 0x0A, // 145
+ 0xFF, 0xFF, 0x00, 0x0A, // 146
+ 0x03, 0xCD, 0x0E, 0x08, // 147
+ 0x03, 0xDB, 0x0A, 0x06, // 148
+ 0xFF, 0xFF, 0x00, 0x0A, // 149
+ 0xFF, 0xFF, 0x00, 0x0A, // 150
+ 0xFF, 0xFF, 0x00, 0x0A, // 151
+ 0x03, 0xE5, 0x0C, 0x07, // 152
+ 0x03, 0xF1, 0x0A, 0x06, // 153
+ 0x03, 0xFB, 0x0C, 0x07, // 154
+ 0x04, 0x07, 0x08, 0x05, // 155
+ 0xFF, 0xFF, 0x00, 0x0A, // 156
+ 0xFF, 0xFF, 0x00, 0x0A, // 157
+ 0xFF, 0xFF, 0x00, 0x0A, // 158
+ 0xFF, 0xFF, 0x00, 0x0A, // 159
+ 0xFF, 0xFF, 0x00, 0x0A, // 160
+ 0x04, 0x0F, 0x04, 0x03, // 161
+ 0x04, 0x13, 0x0A, 0x06, // 162
+ 0x04, 0x1D, 0x0C, 0x07, // 163
+ 0x04, 0x29, 0x0A, 0x06, // 164
+ 0x04, 0x33, 0x0A, 0x06, // 165
+ 0x04, 0x3D, 0x04, 0x03, // 166
+ 0x04, 0x41, 0x0A, 0x06, // 167
+ 0x04, 0x4B, 0x05, 0x04, // 168
+ 0x04, 0x50, 0x0D, 0x08, // 169
+ 0x04, 0x5D, 0x07, 0x05, // 170
+ 0x04, 0x64, 0x0A, 0x06, // 171
+ 0x04, 0x6E, 0x09, 0x06, // 172
+ 0x04, 0x77, 0x03, 0x03, // 173
+ 0x04, 0x7A, 0x0D, 0x08, // 174
+ 0x04, 0x87, 0x0B, 0x07, // 175
+ 0x04, 0x92, 0x07, 0x05, // 176
+ 0x04, 0x99, 0x0A, 0x06, // 177
+ 0x04, 0xA3, 0x05, 0x04, // 178
+ 0x04, 0xA8, 0x05, 0x04, // 179
+ 0x04, 0xAD, 0x05, 0x04, // 180
+ 0x04, 0xB2, 0x0A, 0x06, // 181
+ 0x04, 0xBC, 0x09, 0x06, // 182
+ 0x04, 0xC5, 0x03, 0x03, // 183
+ 0x04, 0xC8, 0x06, 0x04, // 184
+ 0x04, 0xCE, 0x0C, 0x07, // 185
+ 0x04, 0xDA, 0x07, 0x05, // 186
+ 0x04, 0xE1, 0x0C, 0x07, // 187
+ 0x04, 0xED, 0x0A, 0x06, // 188
+ 0x04, 0xF7, 0x10, 0x09, // 189
+ 0x05, 0x07, 0x10, 0x09, // 190
+ 0x05, 0x17, 0x0A, 0x06, // 191
+ 0x05, 0x21, 0x0E, 0x08, // 192
+ 0x05, 0x2F, 0x0E, 0x08, // 193
+ 0x05, 0x3D, 0x0E, 0x08, // 194
+ 0x05, 0x4B, 0x0E, 0x08, // 195
+ 0x05, 0x59, 0x0E, 0x08, // 196
+ 0x05, 0x67, 0x0E, 0x08, // 197
+ 0x05, 0x75, 0x12, 0x0A, // 198
+ 0x05, 0x87, 0x0C, 0x07, // 199
+ 0x05, 0x93, 0x0C, 0x07, // 200
+ 0x05, 0x9F, 0x0C, 0x07, // 201
+ 0x05, 0xAB, 0x0C, 0x07, // 202
+ 0x05, 0xB7, 0x0C, 0x07, // 203
+ 0x05, 0xC3, 0x05, 0x04, // 204
+ 0x05, 0xC8, 0x04, 0x03, // 205
+ 0x05, 0xCC, 0x04, 0x03, // 206
+ 0x05, 0xD0, 0x05, 0x04, // 207
+ 0x05, 0xD5, 0x0B, 0x07, // 208
+ 0x05, 0xE0, 0x0C, 0x07, // 209
+ 0x05, 0xEC, 0x0E, 0x08, // 210
+ 0x05, 0xFA, 0x0E, 0x08, // 211
+ 0x06, 0x08, 0x0E, 0x08, // 212
+ 0x06, 0x16, 0x0E, 0x08, // 213
+ 0x06, 0x24, 0x0E, 0x08, // 214
+ 0x06, 0x32, 0x0A, 0x06, // 215
+ 0x06, 0x3C, 0x0D, 0x08, // 216
+ 0x06, 0x49, 0x0C, 0x07, // 217
+ 0x06, 0x55, 0x0C, 0x07, // 218
+ 0x06, 0x61, 0x0C, 0x07, // 219
+ 0x06, 0x6D, 0x0C, 0x07, // 220
+ 0x06, 0x79, 0x0D, 0x08, // 221
+ 0x06, 0x86, 0x0B, 0x07, // 222
+ 0x06, 0x91, 0x0C, 0x07, // 223
+ 0x06, 0x9D, 0x0A, 0x06, // 224
+ 0x06, 0xA7, 0x0A, 0x06, // 225
+ 0x06, 0xB1, 0x0A, 0x06, // 226
+ 0x06, 0xBB, 0x0A, 0x06, // 227
+ 0x06, 0xC5, 0x0A, 0x06, // 228
+ 0x06, 0xCF, 0x0A, 0x06, // 229
+ 0x06, 0xD9, 0x10, 0x09, // 230
+ 0x06, 0xE9, 0x0A, 0x06, // 231
+ 0x06, 0xF3, 0x0A, 0x06, // 232
+ 0x06, 0xFD, 0x0A, 0x06, // 233
+ 0x07, 0x07, 0x0A, 0x06, // 234
+ 0x07, 0x11, 0x0A, 0x06, // 235
+ 0x07, 0x1B, 0x05, 0x04, // 236
+ 0x07, 0x20, 0x04, 0x03, // 237
+ 0x07, 0x24, 0x05, 0x04, // 238
+ 0x07, 0x29, 0x05, 0x04, // 239
+ 0x07, 0x2E, 0x0A, 0x06, // 240
+ 0x07, 0x38, 0x0A, 0x06, // 241
+ 0x07, 0x42, 0x0A, 0x06, // 242
+ 0x07, 0x4C, 0x0A, 0x06, // 243
+ 0x07, 0x56, 0x0A, 0x06, // 244
+ 0x07, 0x60, 0x0A, 0x06, // 245
+ 0x07, 0x6A, 0x0A, 0x06, // 246
+ 0x07, 0x74, 0x09, 0x06, // 247
+ 0x07, 0x7D, 0x0A, 0x06, // 248
+ 0x07, 0x87, 0x0A, 0x06, // 249
+ 0x07, 0x91, 0x0A, 0x06, // 250
+ 0x07, 0x9B, 0x0A, 0x06, // 251
+ 0x07, 0xA5, 0x0A, 0x06, // 252
+ 0x07, 0xAF, 0x09, 0x06, // 253
+ 0x07, 0xB8, 0x0A, 0x06, // 254
+ 0x07, 0xC2, 0x09, 0x06, // 255
+ // Font Data:
+ 0x00, 0x00, 0xF8, 0x02, // 33
+ 0x38, 0x00, 0x00, 0x00, 0x38, // 34
+ 0xA0, 0x03, 0xE0, 0x00, 0xB8, 0x03, 0xE0, 0x00, 0xB8, // 35
+ 0x30, 0x01, 0x28, 0x02, 0xF8, 0x07, 0x48, 0x02, 0x90, 0x01, // 36
+ 0x00, 0x00, 0x30, 0x00, 0x48, 0x00, 0x30, 0x03, 0xC0, 0x00, 0xB0, 0x01, 0x48, 0x02, 0x80, 0x01, // 37
+ 0x80, 0x01, 0x50, 0x02, 0x68, 0x02, 0xA8, 0x02, 0x18, 0x01, 0x80, 0x03, 0x80, 0x02, // 38
+ 0x38, // 39
+ 0xE0, 0x03, 0x10, 0x04, 0x08, 0x08, // 40
+ 0x08, 0x08, 0x10, 0x04, 0xE0, 0x03, // 41
+ 0x28, 0x00, 0x18, 0x00, 0x28, // 42
+ 0x40, 0x00, 0x40, 0x00, 0xF0, 0x01, 0x40, 0x00, 0x40, // 43
+ 0x00, 0x00, 0x00, 0x06, // 44
+ 0x80, 0x00, 0x80, // 45
+ 0x00, 0x00, 0x00, 0x02, // 46
+ 0x00, 0x03, 0xE0, 0x00, 0x18, // 47
+ 0xF0, 0x01, 0x08, 0x02, 0x08, 0x02, 0x08, 0x02, 0xF0, 0x01, // 48
+ 0x00, 0x00, 0x20, 0x00, 0x10, 0x00, 0xF8, 0x03, // 49
+ 0x10, 0x02, 0x08, 0x03, 0x88, 0x02, 0x48, 0x02, 0x30, 0x02, // 50
+ 0x10, 0x01, 0x08, 0x02, 0x48, 0x02, 0x48, 0x02, 0xB0, 0x01, // 51
+ 0xC0, 0x00, 0xA0, 0x00, 0x90, 0x00, 0x88, 0x00, 0xF8, 0x03, 0x80, // 52
+ 0x60, 0x01, 0x38, 0x02, 0x28, 0x02, 0x28, 0x02, 0xC8, 0x01, // 53
+ 0xF0, 0x01, 0x28, 0x02, 0x28, 0x02, 0x28, 0x02, 0xD0, 0x01, // 54
+ 0x08, 0x00, 0x08, 0x03, 0xC8, 0x00, 0x38, 0x00, 0x08, // 55
+ 0xB0, 0x01, 0x48, 0x02, 0x48, 0x02, 0x48, 0x02, 0xB0, 0x01, // 56
+ 0x70, 0x01, 0x88, 0x02, 0x88, 0x02, 0x88, 0x02, 0xF0, 0x01, // 57
+ 0x00, 0x00, 0x20, 0x02, // 58
+ 0x00, 0x00, 0x20, 0x06, // 59
+ 0x00, 0x00, 0x40, 0x00, 0xA0, 0x00, 0xA0, 0x00, 0x10, 0x01, // 60
+ 0xA0, 0x00, 0xA0, 0x00, 0xA0, 0x00, 0xA0, 0x00, 0xA0, // 61
+ 0x00, 0x00, 0x10, 0x01, 0xA0, 0x00, 0xA0, 0x00, 0x40, // 62
+ 0x10, 0x00, 0x08, 0x00, 0x08, 0x00, 0xC8, 0x02, 0x48, 0x00, 0x30, // 63
+ 0x00, 0x00, 0xC0, 0x03, 0x30, 0x04, 0xD0, 0x09, 0x28, 0x0A, 0x28, 0x0A, 0xC8, 0x0B, 0x68, 0x0A, 0x10, 0x05, 0xE0, 0x04, // 64
+ 0x00, 0x02, 0xC0, 0x01, 0xB0, 0x00, 0x88, 0x00, 0xB0, 0x00, 0xC0, 0x01, 0x00, 0x02, // 65
+ 0x00, 0x00, 0xF8, 0x03, 0x48, 0x02, 0x48, 0x02, 0x48, 0x02, 0xF0, 0x01, // 66
+ 0x00, 0x00, 0xF0, 0x01, 0x08, 0x02, 0x08, 0x02, 0x08, 0x02, 0x10, 0x01, // 67
+ 0x00, 0x00, 0xF8, 0x03, 0x08, 0x02, 0x08, 0x02, 0x10, 0x01, 0xE0, // 68
+ 0x00, 0x00, 0xF8, 0x03, 0x48, 0x02, 0x48, 0x02, 0x48, 0x02, 0x48, 0x02, // 69
+ 0x00, 0x00, 0xF8, 0x03, 0x48, 0x00, 0x48, 0x00, 0x08, // 70
+ 0x00, 0x00, 0xE0, 0x00, 0x10, 0x01, 0x08, 0x02, 0x48, 0x02, 0x50, 0x01, 0xC0, // 71
+ 0x00, 0x00, 0xF8, 0x03, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0xF8, 0x03, // 72
+ 0x00, 0x00, 0xF8, 0x03, // 73
+ 0x00, 0x03, 0x00, 0x02, 0x00, 0x02, 0xF8, 0x01, // 74
+ 0x00, 0x00, 0xF8, 0x03, 0x80, 0x00, 0x60, 0x00, 0x90, 0x00, 0x08, 0x01, 0x00, 0x02, // 75
+ 0x00, 0x00, 0xF8, 0x03, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, // 76
+ 0x00, 0x00, 0xF8, 0x03, 0x30, 0x00, 0xC0, 0x01, 0x00, 0x02, 0xC0, 0x01, 0x30, 0x00, 0xF8, 0x03, // 77
+ 0x00, 0x00, 0xF8, 0x03, 0x30, 0x00, 0x40, 0x00, 0x80, 0x01, 0xF8, 0x03, // 78
+ 0x00, 0x00, 0xF0, 0x01, 0x08, 0x02, 0x08, 0x02, 0x08, 0x02, 0x08, 0x02, 0xF0, 0x01, // 79
+ 0x00, 0x00, 0xF8, 0x03, 0x48, 0x00, 0x48, 0x00, 0x48, 0x00, 0x30, // 80
+ 0x00, 0x00, 0xF0, 0x01, 0x08, 0x02, 0x08, 0x02, 0x08, 0x03, 0x08, 0x03, 0xF0, 0x02, // 81
+ 0x00, 0x00, 0xF8, 0x03, 0x48, 0x00, 0x48, 0x00, 0xC8, 0x00, 0x30, 0x03, // 82
+ 0x00, 0x00, 0x30, 0x01, 0x48, 0x02, 0x48, 0x02, 0x48, 0x02, 0x90, 0x01, // 83
+ 0x00, 0x00, 0x08, 0x00, 0x08, 0x00, 0xF8, 0x03, 0x08, 0x00, 0x08, // 84
+ 0x00, 0x00, 0xF8, 0x01, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0xF8, 0x01, // 85
+ 0x08, 0x00, 0x70, 0x00, 0x80, 0x01, 0x00, 0x02, 0x80, 0x01, 0x70, 0x00, 0x08, // 86
+ 0x18, 0x00, 0xE0, 0x01, 0x00, 0x02, 0xF0, 0x01, 0x08, 0x00, 0xF0, 0x01, 0x00, 0x02, 0xE0, 0x01, 0x18, // 87
+ 0x00, 0x02, 0x08, 0x01, 0x90, 0x00, 0x60, 0x00, 0x90, 0x00, 0x08, 0x01, 0x00, 0x02, // 88
+ 0x08, 0x00, 0x10, 0x00, 0x20, 0x00, 0xC0, 0x03, 0x20, 0x00, 0x10, 0x00, 0x08, // 89
+ 0x08, 0x03, 0x88, 0x02, 0xC8, 0x02, 0x68, 0x02, 0x38, 0x02, 0x18, 0x02, // 90
+ 0x00, 0x00, 0xF8, 0x0F, 0x08, 0x08, // 91
+ 0x18, 0x00, 0xE0, 0x00, 0x00, 0x03, // 92
+ 0x08, 0x08, 0xF8, 0x0F, // 93
+ 0x40, 0x00, 0x30, 0x00, 0x08, 0x00, 0x30, 0x00, 0x40, // 94
+ 0x00, 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, 0x08, // 95
+ 0x08, 0x00, 0x10, // 96
+ 0x00, 0x00, 0x00, 0x03, 0xA0, 0x02, 0xA0, 0x02, 0xE0, 0x03, // 97
+ 0x00, 0x00, 0xF8, 0x03, 0x20, 0x02, 0x20, 0x02, 0xC0, 0x01, // 98
+ 0x00, 0x00, 0xC0, 0x01, 0x20, 0x02, 0x20, 0x02, 0x40, 0x01, // 99
+ 0x00, 0x00, 0xC0, 0x01, 0x20, 0x02, 0x20, 0x02, 0xF8, 0x03, // 100
+ 0x00, 0x00, 0xC0, 0x01, 0xA0, 0x02, 0xA0, 0x02, 0xC0, 0x02, // 101
+ 0x20, 0x00, 0xF0, 0x03, 0x28, // 102
+ 0x00, 0x00, 0xC0, 0x05, 0x20, 0x0A, 0x20, 0x0A, 0xE0, 0x07, // 103
+ 0x00, 0x00, 0xF8, 0x03, 0x20, 0x00, 0x20, 0x00, 0xC0, 0x03, // 104
+ 0x00, 0x00, 0xE8, 0x03, // 105
+ 0x00, 0x08, 0xE8, 0x07, // 106
+ 0xF8, 0x03, 0x80, 0x00, 0xC0, 0x01, 0x20, 0x02, // 107
+ 0x00, 0x00, 0xF8, 0x03, // 108
+ 0x00, 0x00, 0xE0, 0x03, 0x20, 0x00, 0x20, 0x00, 0xE0, 0x03, 0x20, 0x00, 0x20, 0x00, 0xC0, 0x03, // 109
+ 0x00, 0x00, 0xE0, 0x03, 0x20, 0x00, 0x20, 0x00, 0xC0, 0x03, // 110
+ 0x00, 0x00, 0xC0, 0x01, 0x20, 0x02, 0x20, 0x02, 0xC0, 0x01, // 111
+ 0x00, 0x00, 0xE0, 0x0F, 0x20, 0x02, 0x20, 0x02, 0xC0, 0x01, // 112
+ 0x00, 0x00, 0xC0, 0x01, 0x20, 0x02, 0x20, 0x02, 0xE0, 0x0F, // 113
+ 0x00, 0x00, 0xE0, 0x03, 0x20, // 114
+ 0x40, 0x02, 0xA0, 0x02, 0xA0, 0x02, 0x20, 0x01, // 115
+ 0x20, 0x00, 0xF8, 0x03, 0x20, 0x02, // 116
+ 0x00, 0x00, 0xE0, 0x01, 0x00, 0x02, 0x00, 0x02, 0xE0, 0x03, // 117
+ 0x20, 0x00, 0xC0, 0x01, 0x00, 0x02, 0xC0, 0x01, 0x20, // 118
+ 0xE0, 0x01, 0x00, 0x02, 0xC0, 0x01, 0x20, 0x00, 0xC0, 0x01, 0x00, 0x02, 0xE0, 0x01, // 119
+ 0x20, 0x02, 0x40, 0x01, 0x80, 0x00, 0x40, 0x01, 0x20, 0x02, // 120
+ 0x20, 0x00, 0xC0, 0x09, 0x00, 0x06, 0xC0, 0x01, 0x20, // 121
+ 0x20, 0x02, 0x20, 0x03, 0xA0, 0x02, 0x60, 0x02, 0x20, 0x02, // 122
+ 0x80, 0x00, 0x78, 0x0F, 0x08, 0x08, // 123
+ 0x00, 0x00, 0xF8, 0x0F, // 124
+ 0x08, 0x08, 0x78, 0x0F, 0x80, // 125
+ 0xC0, 0x00, 0x40, 0x00, 0xC0, 0x00, 0x80, 0x00, 0xC0, // 126
+ 0x00, 0x00, 0xF8, 0x03, 0x40, 0x02, 0x20, 0x02, 0x00, 0x02, 0x00, 0x02, // 129
+ 0x40, 0x00, 0xF8, 0x03, 0x20, // 130
+ 0x00, 0x00, 0xF8, 0x03, 0x30, 0x00, 0x44, 0x00, 0x82, 0x01, 0xF8, 0x03, // 131
+ 0x00, 0x02, 0xC0, 0x01, 0xB0, 0x00, 0x88, 0x00, 0xB0, 0x00, 0xC0, 0x0D, 0x00, 0x0A, // 132
+ 0x00, 0x00, 0x00, 0x03, 0xA0, 0x02, 0xA0, 0x0E, 0xE0, 0x0B, // 133
+ 0x00, 0x00, 0xF0, 0x01, 0x08, 0x02, 0x0A, 0x02, 0x09, 0x02, 0x10, 0x01, // 134
+ 0x00, 0x00, 0xC0, 0x01, 0x20, 0x02, 0x28, 0x02, 0x44, 0x01, // 135
+ 0x00, 0x00, 0xE0, 0x03, 0x20, 0x00, 0x28, 0x00, 0xC4, 0x03, // 136
+ 0x20, 0x02, 0x20, 0x03, 0xA8, 0x02, 0x64, 0x02, 0x20, 0x02, // 137
+ 0x00, 0x00, 0xF0, 0x01, 0x08, 0x02, 0x08, 0x02, 0x0A, 0x02, 0x09, 0x02, 0xF0, 0x01, // 147
+ 0x00, 0x00, 0xC0, 0x01, 0x20, 0x02, 0x28, 0x02, 0xC4, 0x01, // 148
+ 0x00, 0x00, 0xF8, 0x03, 0x48, 0x02, 0x48, 0x0E, 0x48, 0x0A, 0x48, 0x02, // 152
+ 0x00, 0x00, 0xC0, 0x01, 0xA0, 0x02, 0xA0, 0x0E, 0xC0, 0x0A, // 153
+ 0x00, 0x00, 0x30, 0x01, 0x48, 0x02, 0x4A, 0x02, 0x49, 0x02, 0x90, 0x01, // 154
+ 0x40, 0x02, 0xA0, 0x02, 0xA8, 0x02, 0x24, 0x01, // 155
+ 0x00, 0x00, 0xA0, 0x0F, // 161
+ 0x00, 0x00, 0xC0, 0x01, 0xA0, 0x0F, 0x78, 0x02, 0x40, 0x01, // 162
+ 0x40, 0x02, 0x70, 0x03, 0xC8, 0x02, 0x48, 0x02, 0x08, 0x02, 0x10, 0x02, // 163
+ 0x00, 0x00, 0xE0, 0x01, 0x20, 0x01, 0x20, 0x01, 0xE0, 0x01, // 164
+ 0x48, 0x01, 0x70, 0x01, 0xC0, 0x03, 0x70, 0x01, 0x48, 0x01, // 165
+ 0x00, 0x00, 0x38, 0x0F, // 166
+ 0xD0, 0x04, 0x28, 0x09, 0x48, 0x09, 0x48, 0x0A, 0x90, 0x05, // 167
+ 0x08, 0x00, 0x00, 0x00, 0x08, // 168
+ 0xE0, 0x00, 0x10, 0x01, 0x48, 0x02, 0xA8, 0x02, 0xA8, 0x02, 0x10, 0x01, 0xE0, // 169
+ 0x68, 0x00, 0x68, 0x00, 0x68, 0x00, 0x78, // 170
+ 0x00, 0x00, 0x80, 0x01, 0x40, 0x02, 0x80, 0x01, 0x40, 0x02, // 171
+ 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0xE0, // 172
+ 0x80, 0x00, 0x80, // 173
+ 0xE0, 0x00, 0x10, 0x01, 0xE8, 0x02, 0x68, 0x02, 0xC8, 0x02, 0x10, 0x01, 0xE0, // 174
+ 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, // 175
+ 0x00, 0x00, 0x38, 0x00, 0x28, 0x00, 0x38, // 176
+ 0x40, 0x02, 0x40, 0x02, 0xF0, 0x03, 0x40, 0x02, 0x40, 0x02, // 177
+ 0x48, 0x00, 0x68, 0x00, 0x58, // 178
+ 0x48, 0x00, 0x58, 0x00, 0x68, // 179
+ 0x00, 0x00, 0x10, 0x00, 0x08, // 180
+ 0x00, 0x00, 0xE0, 0x0F, 0x00, 0x02, 0x00, 0x02, 0xE0, 0x03, // 181
+ 0x70, 0x00, 0xF8, 0x0F, 0x08, 0x00, 0xF8, 0x0F, 0x08, // 182
+ 0x00, 0x00, 0x40, // 183
+ 0x00, 0x00, 0x00, 0x14, 0x00, 0x18, // 184
+ 0x08, 0x03, 0x88, 0x02, 0xCA, 0x02, 0x69, 0x02, 0x38, 0x02, 0x18, 0x02, // 185
+ 0x30, 0x00, 0x48, 0x00, 0x48, 0x00, 0x30, // 186
+ 0x08, 0x03, 0x88, 0x02, 0xC8, 0x02, 0x6A, 0x02, 0x38, 0x02, 0x18, 0x02, // 187
+ 0x20, 0x02, 0x20, 0x03, 0xA8, 0x02, 0x60, 0x02, 0x20, 0x02, // 188
+ 0x00, 0x00, 0x10, 0x02, 0x78, 0x01, 0x80, 0x00, 0x60, 0x00, 0x50, 0x02, 0x48, 0x03, 0xC0, 0x02, // 189
+ 0x48, 0x00, 0x58, 0x00, 0x68, 0x03, 0x80, 0x00, 0x60, 0x01, 0x90, 0x01, 0xC8, 0x03, 0x00, 0x01, // 190
+ 0x00, 0x00, 0x00, 0x06, 0x00, 0x09, 0xA0, 0x09, 0x00, 0x04, // 191
+ 0x00, 0x02, 0xC0, 0x01, 0xB0, 0x00, 0x89, 0x00, 0xB2, 0x00, 0xC0, 0x01, 0x00, 0x02, // 192
+ 0x00, 0x02, 0xC0, 0x01, 0xB0, 0x00, 0x8A, 0x00, 0xB1, 0x00, 0xC0, 0x01, 0x00, 0x02, // 193
+ 0x00, 0x02, 0xC0, 0x01, 0xB2, 0x00, 0x89, 0x00, 0xB2, 0x00, 0xC0, 0x01, 0x00, 0x02, // 194
+ 0x00, 0x02, 0xC2, 0x01, 0xB1, 0x00, 0x8A, 0x00, 0xB1, 0x00, 0xC0, 0x01, 0x00, 0x02, // 195
+ 0x00, 0x02, 0xC0, 0x01, 0xB2, 0x00, 0x88, 0x00, 0xB2, 0x00, 0xC0, 0x01, 0x00, 0x02, // 196
+ 0x00, 0x02, 0xC0, 0x01, 0xBE, 0x00, 0x8A, 0x00, 0xBE, 0x00, 0xC0, 0x01, 0x00, 0x02, // 197
+ 0x00, 0x03, 0xC0, 0x00, 0xE0, 0x00, 0x98, 0x00, 0x88, 0x00, 0xF8, 0x03, 0x48, 0x02, 0x48, 0x02, 0x48, 0x02, // 198
+ 0x00, 0x00, 0xF0, 0x01, 0x08, 0x02, 0x08, 0x16, 0x08, 0x1A, 0x10, 0x01, // 199
+ 0x00, 0x00, 0xF8, 0x03, 0x49, 0x02, 0x4A, 0x02, 0x48, 0x02, 0x48, 0x02, // 200
+ 0x00, 0x00, 0xF8, 0x03, 0x48, 0x02, 0x4A, 0x02, 0x49, 0x02, 0x48, 0x02, // 201
+ 0x00, 0x00, 0xFA, 0x03, 0x49, 0x02, 0x4A, 0x02, 0x48, 0x02, 0x48, 0x02, // 202
+ 0x00, 0x00, 0xF8, 0x03, 0x4A, 0x02, 0x48, 0x02, 0x4A, 0x02, 0x48, 0x02, // 203
+ 0x00, 0x00, 0xF9, 0x03, 0x02, // 204
+ 0x02, 0x00, 0xF9, 0x03, // 205
+ 0x01, 0x00, 0xFA, 0x03, // 206
+ 0x02, 0x00, 0xF8, 0x03, 0x02, // 207
+ 0x40, 0x00, 0xF8, 0x03, 0x48, 0x02, 0x48, 0x02, 0x10, 0x01, 0xE0, // 208
+ 0x00, 0x00, 0xFA, 0x03, 0x31, 0x00, 0x42, 0x00, 0x81, 0x01, 0xF8, 0x03, // 209
+ 0x00, 0x00, 0xF0, 0x01, 0x08, 0x02, 0x09, 0x02, 0x0A, 0x02, 0x08, 0x02, 0xF0, 0x01, // 210
+ 0x00, 0x00, 0xF0, 0x01, 0x08, 0x02, 0x0A, 0x02, 0x09, 0x02, 0x08, 0x02, 0xF0, 0x01, // 211
+ 0x00, 0x00, 0xF0, 0x01, 0x08, 0x02, 0x0A, 0x02, 0x09, 0x02, 0x0A, 0x02, 0xF0, 0x01, // 212
+ 0x00, 0x00, 0xF0, 0x01, 0x0A, 0x02, 0x09, 0x02, 0x0A, 0x02, 0x09, 0x02, 0xF0, 0x01, // 213
+ 0x00, 0x00, 0xF0, 0x01, 0x0A, 0x02, 0x08, 0x02, 0x0A, 0x02, 0x08, 0x02, 0xF0, 0x01, // 214
+ 0x10, 0x01, 0xA0, 0x00, 0xE0, 0x00, 0xA0, 0x00, 0x10, 0x01, // 215
+ 0x00, 0x00, 0xF0, 0x02, 0x08, 0x03, 0xC8, 0x02, 0x28, 0x02, 0x18, 0x03, 0xE8, // 216
+ 0x00, 0x00, 0xF8, 0x01, 0x01, 0x02, 0x02, 0x02, 0x00, 0x02, 0xF8, 0x01, // 217
+ 0x00, 0x00, 0xF8, 0x01, 0x02, 0x02, 0x01, 0x02, 0x00, 0x02, 0xF8, 0x01, // 218
+ 0x00, 0x00, 0xF8, 0x01, 0x02, 0x02, 0x01, 0x02, 0x02, 0x02, 0xF8, 0x01, // 219
+ 0x00, 0x00, 0xF8, 0x01, 0x02, 0x02, 0x00, 0x02, 0x02, 0x02, 0xF8, 0x01, // 220
+ 0x08, 0x00, 0x10, 0x00, 0x20, 0x00, 0xC2, 0x03, 0x21, 0x00, 0x10, 0x00, 0x08, // 221
+ 0x00, 0x00, 0xF8, 0x03, 0x10, 0x01, 0x10, 0x01, 0x10, 0x01, 0xE0, // 222
+ 0x00, 0x00, 0xF0, 0x03, 0x08, 0x01, 0x48, 0x02, 0xB0, 0x02, 0x80, 0x01, // 223
+ 0x00, 0x00, 0x00, 0x03, 0xA4, 0x02, 0xA8, 0x02, 0xE0, 0x03, // 224
+ 0x00, 0x00, 0x00, 0x03, 0xA8, 0x02, 0xA4, 0x02, 0xE0, 0x03, // 225
+ 0x00, 0x00, 0x00, 0x03, 0xA8, 0x02, 0xA4, 0x02, 0xE8, 0x03, // 226
+ 0x00, 0x00, 0x08, 0x03, 0xA4, 0x02, 0xA8, 0x02, 0xE4, 0x03, // 227
+ 0x00, 0x00, 0x00, 0x03, 0xA8, 0x02, 0xA0, 0x02, 0xE8, 0x03, // 228
+ 0x00, 0x00, 0x00, 0x03, 0xAE, 0x02, 0xAA, 0x02, 0xEE, 0x03, // 229
+ 0x00, 0x00, 0x40, 0x03, 0xA0, 0x02, 0xA0, 0x02, 0xC0, 0x01, 0xA0, 0x02, 0xA0, 0x02, 0xC0, 0x02, // 230
+ 0x00, 0x00, 0xC0, 0x01, 0x20, 0x16, 0x20, 0x1A, 0x40, 0x01, // 231
+ 0x00, 0x00, 0xC0, 0x01, 0xA4, 0x02, 0xA8, 0x02, 0xC0, 0x02, // 232
+ 0x00, 0x00, 0xC0, 0x01, 0xA8, 0x02, 0xA4, 0x02, 0xC0, 0x02, // 233
+ 0x00, 0x00, 0xC0, 0x01, 0xA8, 0x02, 0xA4, 0x02, 0xC8, 0x02, // 234
+ 0x00, 0x00, 0xC0, 0x01, 0xA8, 0x02, 0xA0, 0x02, 0xC8, 0x02, // 235
+ 0x00, 0x00, 0xE4, 0x03, 0x08, // 236
+ 0x08, 0x00, 0xE4, 0x03, // 237
+ 0x08, 0x00, 0xE4, 0x03, 0x08, // 238
+ 0x08, 0x00, 0xE0, 0x03, 0x08, // 239
+ 0x00, 0x00, 0xC0, 0x01, 0x28, 0x02, 0x38, 0x02, 0xE0, 0x01, // 240
+ 0x00, 0x00, 0xE8, 0x03, 0x24, 0x00, 0x28, 0x00, 0xC4, 0x03, // 241
+ 0x00, 0x00, 0xC0, 0x01, 0x24, 0x02, 0x28, 0x02, 0xC0, 0x01, // 242
+ 0x00, 0x00, 0xC0, 0x01, 0x28, 0x02, 0x24, 0x02, 0xC0, 0x01, // 243
+ 0x00, 0x00, 0xC0, 0x01, 0x28, 0x02, 0x24, 0x02, 0xC8, 0x01, // 244
+ 0x00, 0x00, 0xC8, 0x01, 0x24, 0x02, 0x28, 0x02, 0xC4, 0x01, // 245
+ 0x00, 0x00, 0xC0, 0x01, 0x28, 0x02, 0x20, 0x02, 0xC8, 0x01, // 246
+ 0x40, 0x00, 0x40, 0x00, 0x50, 0x01, 0x40, 0x00, 0x40, // 247
+ 0x00, 0x00, 0xC0, 0x02, 0xA0, 0x03, 0x60, 0x02, 0xA0, 0x01, // 248
+ 0x00, 0x00, 0xE0, 0x01, 0x04, 0x02, 0x08, 0x02, 0xE0, 0x03, // 249
+ 0x00, 0x00, 0xE0, 0x01, 0x08, 0x02, 0x04, 0x02, 0xE0, 0x03, // 250
+ 0x00, 0x00, 0xE8, 0x01, 0x04, 0x02, 0x08, 0x02, 0xE0, 0x03, // 251
+ 0x00, 0x00, 0xE0, 0x01, 0x08, 0x02, 0x00, 0x02, 0xE8, 0x03, // 252
+ 0x20, 0x00, 0xC0, 0x09, 0x08, 0x06, 0xC4, 0x01, 0x20, // 253
+ 0x00, 0x00, 0xF8, 0x0F, 0x20, 0x02, 0x20, 0x02, 0xC0, 0x01, // 254
+ 0x20, 0x00, 0xC8, 0x09, 0x00, 0x06, 0xC8, 0x01, 0x20, // 255
};
const uint8_t ArialMT_Plain_16_PL[] PROGMEM = {
-0x10, // Width: 16
-0x13, // Height: 19
-0x20, // First char: 32
-0xE0, // Number of chars: 224
-// Jump Table:
-0xFF, 0xFF, 0x00, 0x04, // 32
-0x00, 0x00, 0x08, 0x04, // 33
-0x00, 0x08, 0x0D, 0x06, // 34
-0x00, 0x15, 0x1A, 0x0A, // 35
-0x00, 0x2F, 0x17, 0x09, // 36
-0x00, 0x46, 0x26, 0x0E, // 37
-0x00, 0x6C, 0x1D, 0x0B, // 38
-0x00, 0x89, 0x04, 0x03, // 39
-0x00, 0x8D, 0x0C, 0x05, // 40
-0x00, 0x99, 0x0B, 0x05, // 41
-0x00, 0xA4, 0x0D, 0x06, // 42
-0x00, 0xB1, 0x17, 0x09, // 43
-0x00, 0xC8, 0x09, 0x04, // 44
-0x00, 0xD1, 0x0B, 0x05, // 45
-0x00, 0xDC, 0x08, 0x04, // 46
-0x00, 0xE4, 0x0A, 0x05, // 47
-0x00, 0xEE, 0x17, 0x09, // 48
-0x01, 0x05, 0x11, 0x07, // 49
-0x01, 0x16, 0x17, 0x09, // 50
-0x01, 0x2D, 0x17, 0x09, // 51
-0x01, 0x44, 0x17, 0x09, // 52
-0x01, 0x5B, 0x17, 0x09, // 53
-0x01, 0x72, 0x17, 0x09, // 54
-0x01, 0x89, 0x16, 0x09, // 55
-0x01, 0x9F, 0x17, 0x09, // 56
-0x01, 0xB6, 0x17, 0x09, // 57
-0x01, 0xCD, 0x05, 0x03, // 58
-0x01, 0xD2, 0x06, 0x03, // 59
-0x01, 0xD8, 0x17, 0x09, // 60
-0x01, 0xEF, 0x17, 0x09, // 61
-0x02, 0x06, 0x17, 0x09, // 62
-0x02, 0x1D, 0x16, 0x09, // 63
-0x02, 0x33, 0x2F, 0x11, // 64
-0x02, 0x62, 0x1D, 0x0B, // 65
-0x02, 0x7F, 0x1D, 0x0B, // 66
-0x02, 0x9C, 0x20, 0x0C, // 67
-0x02, 0xBC, 0x20, 0x0C, // 68
-0x02, 0xDC, 0x1D, 0x0B, // 69
-0x02, 0xF9, 0x19, 0x0A, // 70
-0x03, 0x12, 0x20, 0x0C, // 71
-0x03, 0x32, 0x1D, 0x0B, // 72
-0x03, 0x4F, 0x05, 0x03, // 73
-0x03, 0x54, 0x14, 0x08, // 74
-0x03, 0x68, 0x1D, 0x0B, // 75
-0x03, 0x85, 0x17, 0x09, // 76
-0x03, 0x9C, 0x23, 0x0D, // 77
-0x03, 0xBF, 0x1D, 0x0B, // 78
-0x03, 0xDC, 0x20, 0x0C, // 79
-0x03, 0xFC, 0x1C, 0x0B, // 80
-0x04, 0x18, 0x20, 0x0C, // 81
-0x04, 0x38, 0x1D, 0x0B, // 82
-0x04, 0x55, 0x1D, 0x0B, // 83
-0x04, 0x72, 0x19, 0x0A, // 84
-0x04, 0x8B, 0x1D, 0x0B, // 85
-0x04, 0xA8, 0x1C, 0x0B, // 86
-0x04, 0xC4, 0x2B, 0x10, // 87
-0x04, 0xEF, 0x20, 0x0C, // 88
-0x05, 0x0F, 0x19, 0x0A, // 89
-0x05, 0x28, 0x1A, 0x0A, // 90
-0x05, 0x42, 0x0C, 0x05, // 91
-0x05, 0x4E, 0x0B, 0x05, // 92
-0x05, 0x59, 0x09, 0x04, // 93
-0x05, 0x62, 0x14, 0x08, // 94
-0x05, 0x76, 0x1B, 0x0A, // 95
-0x05, 0x91, 0x07, 0x04, // 96
-0x05, 0x98, 0x17, 0x09, // 97
-0x05, 0xAF, 0x17, 0x09, // 98
-0x05, 0xC6, 0x14, 0x08, // 99
-0x05, 0xDA, 0x17, 0x09, // 100
-0x05, 0xF1, 0x17, 0x09, // 101
-0x06, 0x08, 0x0A, 0x05, // 102
-0x06, 0x12, 0x17, 0x09, // 103
-0x06, 0x29, 0x14, 0x08, // 104
-0x06, 0x3D, 0x05, 0x03, // 105
-0x06, 0x42, 0x06, 0x03, // 106
-0x06, 0x48, 0x17, 0x09, // 107
-0x06, 0x5F, 0x05, 0x03, // 108
-0x06, 0x64, 0x23, 0x0D, // 109
-0x06, 0x87, 0x14, 0x08, // 110
-0x06, 0x9B, 0x17, 0x09, // 111
-0x06, 0xB2, 0x17, 0x09, // 112
-0x06, 0xC9, 0x18, 0x09, // 113
-0x06, 0xE1, 0x0D, 0x06, // 114
-0x06, 0xEE, 0x14, 0x08, // 115
-0x07, 0x02, 0x0B, 0x05, // 116
-0x07, 0x0D, 0x14, 0x08, // 117
-0x07, 0x21, 0x13, 0x08, // 118
-0x07, 0x34, 0x1F, 0x0C, // 119
-0x07, 0x53, 0x14, 0x08, // 120
-0x07, 0x67, 0x13, 0x08, // 121
-0x07, 0x7A, 0x14, 0x08, // 122
-0x07, 0x8E, 0x0F, 0x06, // 123
-0x07, 0x9D, 0x06, 0x03, // 124
-0x07, 0xA3, 0x0E, 0x06, // 125
-0x07, 0xB1, 0x17, 0x09, // 126
-0xFF, 0xFF, 0x00, 0x10, // 127
-0xFF, 0xFF, 0x00, 0x10, // 128
-0x07, 0xC8, 0x17, 0x09, // 129
-0x07, 0xDF, 0x07, 0x04, // 130
-0x07, 0xE6, 0x1D, 0x0B, // 131
-0x08, 0x03, 0x1E, 0x0B, // 132
-0x08, 0x21, 0x1B, 0x0A, // 133
-0x08, 0x3C, 0x20, 0x0C, // 134
-0x08, 0x5C, 0x14, 0x08, // 135
-0x08, 0x70, 0x14, 0x08, // 136
-0x08, 0x84, 0x14, 0x08, // 137
-0xFF, 0xFF, 0x00, 0x10, // 138
-0xFF, 0xFF, 0x00, 0x10, // 139
-0xFF, 0xFF, 0x00, 0x10, // 140
-0xFF, 0xFF, 0x00, 0x10, // 141
-0xFF, 0xFF, 0x00, 0x10, // 142
-0xFF, 0xFF, 0x00, 0x10, // 143
-0xFF, 0xFF, 0x00, 0x10, // 144
-0xFF, 0xFF, 0x00, 0x10, // 145
-0xFF, 0xFF, 0x00, 0x10, // 146
-0x08, 0x98, 0x20, 0x0C, // 147
-0x08, 0xB8, 0x17, 0x09, // 148
-0xFF, 0xFF, 0x00, 0x10, // 149
-0xFF, 0xFF, 0x00, 0x10, // 150
-0xFF, 0xFF, 0x00, 0x10, // 151
-0x08, 0xCF, 0x1D, 0x0B, // 152
-0x08, 0xEC, 0x17, 0x09, // 153
-0x09, 0x03, 0x1D, 0x0B, // 154
-0x09, 0x20, 0x14, 0x08, // 155
-0xFF, 0xFF, 0x00, 0x10, // 156
-0xFF, 0xFF, 0x00, 0x10, // 157
-0xFF, 0xFF, 0x00, 0x10, // 158
-0xFF, 0xFF, 0x00, 0x10, // 159
-0xFF, 0xFF, 0x00, 0x10, // 160
-0x09, 0x34, 0x09, 0x04, // 161
-0x09, 0x3D, 0x17, 0x09, // 162
-0x09, 0x54, 0x17, 0x09, // 163
-0x09, 0x6B, 0x14, 0x08, // 164
-0x09, 0x7F, 0x1A, 0x0A, // 165
-0x09, 0x99, 0x06, 0x03, // 166
-0x09, 0x9F, 0x17, 0x09, // 167
-0x09, 0xB6, 0x07, 0x04, // 168
-0x09, 0xBD, 0x23, 0x0D, // 169
-0x09, 0xE0, 0x0E, 0x06, // 170
-0x09, 0xEE, 0x14, 0x08, // 171
-0x0A, 0x02, 0x17, 0x09, // 172
-0x0A, 0x19, 0x0B, 0x05, // 173
-0x0A, 0x24, 0x23, 0x0D, // 174
-0x0A, 0x47, 0x19, 0x0A, // 175
-0x0A, 0x60, 0x0D, 0x06, // 176
-0x0A, 0x6D, 0x17, 0x09, // 177
-0x0A, 0x84, 0x0E, 0x06, // 178
-0x0A, 0x92, 0x0D, 0x06, // 179
-0x0A, 0x9F, 0x0A, 0x05, // 180
-0x0A, 0xA9, 0x17, 0x09, // 181
-0x0A, 0xC0, 0x19, 0x0A, // 182
-0x0A, 0xD9, 0x08, 0x04, // 183
-0x0A, 0xE1, 0x0C, 0x05, // 184
-0x0A, 0xED, 0x1A, 0x0A, // 185
-0x0B, 0x07, 0x0D, 0x06, // 186
-0x0B, 0x14, 0x1A, 0x0A, // 187
-0x0B, 0x2E, 0x14, 0x08, // 188
-0x0B, 0x42, 0x26, 0x0E, // 189
-0x0B, 0x68, 0x26, 0x0E, // 190
-0x0B, 0x8E, 0x1A, 0x0A, // 191
-0x0B, 0xA8, 0x1D, 0x0B, // 192
-0x0B, 0xC5, 0x1D, 0x0B, // 193
-0x0B, 0xE2, 0x1D, 0x0B, // 194
-0x0B, 0xFF, 0x1D, 0x0B, // 195
-0x0C, 0x1C, 0x1D, 0x0B, // 196
-0x0C, 0x39, 0x1D, 0x0B, // 197
-0x0C, 0x56, 0x2C, 0x10, // 198
-0x0C, 0x82, 0x20, 0x0C, // 199
-0x0C, 0xA2, 0x1D, 0x0B, // 200
-0x0C, 0xBF, 0x1D, 0x0B, // 201
-0x0C, 0xDC, 0x1D, 0x0B, // 202
-0x0C, 0xF9, 0x1D, 0x0B, // 203
-0x0D, 0x16, 0x05, 0x03, // 204
-0x0D, 0x1B, 0x07, 0x04, // 205
-0x0D, 0x22, 0x0A, 0x05, // 206
-0x0D, 0x2C, 0x07, 0x04, // 207
-0x0D, 0x33, 0x20, 0x0C, // 208
-0x0D, 0x53, 0x1D, 0x0B, // 209
-0x0D, 0x70, 0x20, 0x0C, // 210
-0x0D, 0x90, 0x20, 0x0C, // 211
-0x0D, 0xB0, 0x20, 0x0C, // 212
-0x0D, 0xD0, 0x20, 0x0C, // 213
-0x0D, 0xF0, 0x20, 0x0C, // 214
-0x0E, 0x10, 0x17, 0x09, // 215
-0x0E, 0x27, 0x20, 0x0C, // 216
-0x0E, 0x47, 0x1D, 0x0B, // 217
-0x0E, 0x64, 0x1D, 0x0B, // 218
-0x0E, 0x81, 0x1D, 0x0B, // 219
-0x0E, 0x9E, 0x1D, 0x0B, // 220
-0x0E, 0xBB, 0x19, 0x0A, // 221
-0x0E, 0xD4, 0x1D, 0x0B, // 222
-0x0E, 0xF1, 0x17, 0x09, // 223
-0x0F, 0x08, 0x17, 0x09, // 224
-0x0F, 0x1F, 0x17, 0x09, // 225
-0x0F, 0x36, 0x17, 0x09, // 226
-0x0F, 0x4D, 0x17, 0x09, // 227
-0x0F, 0x64, 0x17, 0x09, // 228
-0x0F, 0x7B, 0x17, 0x09, // 229
-0x0F, 0x92, 0x29, 0x0F, // 230
-0x0F, 0xBB, 0x14, 0x08, // 231
-0x0F, 0xCF, 0x17, 0x09, // 232
-0x0F, 0xE6, 0x17, 0x09, // 233
-0x0F, 0xFD, 0x17, 0x09, // 234
-0x10, 0x14, 0x17, 0x09, // 235
-0x10, 0x2B, 0x05, 0x03, // 236
-0x10, 0x30, 0x07, 0x04, // 237
-0x10, 0x37, 0x0A, 0x05, // 238
-0x10, 0x41, 0x07, 0x04, // 239
-0x10, 0x48, 0x17, 0x09, // 240
-0x10, 0x5F, 0x14, 0x08, // 241
-0x10, 0x73, 0x17, 0x09, // 242
-0x10, 0x8A, 0x17, 0x09, // 243
-0x10, 0xA1, 0x17, 0x09, // 244
-0x10, 0xB8, 0x17, 0x09, // 245
-0x10, 0xCF, 0x17, 0x09, // 246
-0x10, 0xE6, 0x17, 0x09, // 247
-0x10, 0xFD, 0x17, 0x09, // 248
-0x11, 0x14, 0x14, 0x08, // 249
-0x11, 0x28, 0x14, 0x08, // 250
-0x11, 0x3C, 0x14, 0x08, // 251
-0x11, 0x50, 0x14, 0x08, // 252
-0x11, 0x64, 0x13, 0x08, // 253
-0x11, 0x77, 0x17, 0x09, // 254
-0x11, 0x8E, 0x13, 0x08, // 255
-// Font Data:
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0x5F, // 33
-0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, // 34
-0x80, 0x08, 0x00, 0x80, 0x78, 0x00, 0xC0, 0x0F, 0x00, 0xB8, 0x08, 0x00, 0x80, 0x08, 0x00, 0x80, 0x78, 0x00, 0xC0, 0x0F, 0x00, 0xB8, 0x08, 0x00, 0x80, 0x08, // 35
-0x00, 0x00, 0x00, 0xE0, 0x10, 0x00, 0x10, 0x21, 0x00, 0x08, 0x41, 0x00, 0xFC, 0xFF, 0x00, 0x08, 0x42, 0x00, 0x10, 0x22, 0x00, 0x20, 0x1C, // 36
-0x00, 0x00, 0x00, 0xF0, 0x00, 0x00, 0x08, 0x01, 0x00, 0x08, 0x01, 0x00, 0x08, 0x61, 0x00, 0xF0, 0x18, 0x00, 0x00, 0x06, 0x00, 0xC0, 0x01, 0x00, 0x30, 0x3C, 0x00, 0x08, 0x42, 0x00, 0x00, 0x42, 0x00, 0x00, 0x42, 0x00, 0x00, 0x3C, // 37
-0x00, 0x00, 0x00, 0x00, 0x1C, 0x00, 0x70, 0x22, 0x00, 0x88, 0x41, 0x00, 0x08, 0x43, 0x00, 0x88, 0x44, 0x00, 0x70, 0x28, 0x00, 0x00, 0x10, 0x00, 0x00, 0x28, 0x00, 0x00, 0x44, // 38
-0x00, 0x00, 0x00, 0x78, // 39
-0x00, 0x00, 0x00, 0x80, 0x3F, 0x00, 0x70, 0xC0, 0x01, 0x08, 0x00, 0x02, // 40
-0x00, 0x00, 0x00, 0x08, 0x00, 0x02, 0x70, 0xC0, 0x01, 0x80, 0x3F, // 41
-0x10, 0x00, 0x00, 0xD0, 0x00, 0x00, 0x38, 0x00, 0x00, 0xD0, 0x00, 0x00, 0x10, // 42
-0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x02, 0x00, 0x00, 0x02, 0x00, 0xC0, 0x1F, 0x00, 0x00, 0x02, 0x00, 0x00, 0x02, 0x00, 0x00, 0x02, // 43
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x01, // 44
-0x00, 0x08, 0x00, 0x00, 0x08, 0x00, 0x00, 0x08, 0x00, 0x00, 0x08, // 45
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, // 46
-0x00, 0x60, 0x00, 0x00, 0x1E, 0x00, 0xE0, 0x01, 0x00, 0x18, // 47
-0x00, 0x00, 0x00, 0xE0, 0x1F, 0x00, 0x10, 0x20, 0x00, 0x08, 0x40, 0x00, 0x08, 0x40, 0x00, 0x08, 0x40, 0x00, 0x10, 0x20, 0x00, 0xE0, 0x1F, // 48
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x20, 0x00, 0x00, 0x10, 0x00, 0x00, 0xF8, 0x7F, // 49
-0x00, 0x00, 0x00, 0x20, 0x40, 0x00, 0x10, 0x60, 0x00, 0x08, 0x50, 0x00, 0x08, 0x48, 0x00, 0x08, 0x44, 0x00, 0x10, 0x43, 0x00, 0xE0, 0x40, // 50
-0x00, 0x00, 0x00, 0x20, 0x10, 0x00, 0x10, 0x20, 0x00, 0x08, 0x41, 0x00, 0x08, 0x41, 0x00, 0x88, 0x41, 0x00, 0xF0, 0x22, 0x00, 0x00, 0x1C, // 51
-0x00, 0x0C, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x09, 0x00, 0xC0, 0x08, 0x00, 0x20, 0x08, 0x00, 0x10, 0x08, 0x00, 0xF8, 0x7F, 0x00, 0x00, 0x08, // 52
-0x00, 0x00, 0x00, 0xC0, 0x11, 0x00, 0xB8, 0x20, 0x00, 0x88, 0x40, 0x00, 0x88, 0x40, 0x00, 0x88, 0x40, 0x00, 0x08, 0x21, 0x00, 0x08, 0x1E, // 53
-0x00, 0x00, 0x00, 0xE0, 0x1F, 0x00, 0x10, 0x21, 0x00, 0x88, 0x40, 0x00, 0x88, 0x40, 0x00, 0x88, 0x40, 0x00, 0x10, 0x21, 0x00, 0x20, 0x1E, // 54
-0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x08, 0x00, 0x00, 0x08, 0x78, 0x00, 0x08, 0x07, 0x00, 0xC8, 0x00, 0x00, 0x28, 0x00, 0x00, 0x18, // 55
-0x00, 0x00, 0x00, 0x60, 0x1C, 0x00, 0x90, 0x22, 0x00, 0x08, 0x41, 0x00, 0x08, 0x41, 0x00, 0x08, 0x41, 0x00, 0x90, 0x22, 0x00, 0x60, 0x1C, // 56
-0x00, 0x00, 0x00, 0xE0, 0x11, 0x00, 0x10, 0x22, 0x00, 0x08, 0x44, 0x00, 0x08, 0x44, 0x00, 0x08, 0x44, 0x00, 0x10, 0x22, 0x00, 0xE0, 0x1F, // 57
-0x00, 0x00, 0x00, 0x40, 0x40, // 58
-0x00, 0x00, 0x00, 0x40, 0xC0, 0x01, // 59
-0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x05, 0x00, 0x00, 0x05, 0x00, 0x80, 0x08, 0x00, 0x80, 0x08, 0x00, 0x80, 0x08, 0x00, 0x40, 0x10, // 60
-0x00, 0x00, 0x00, 0x80, 0x08, 0x00, 0x80, 0x08, 0x00, 0x80, 0x08, 0x00, 0x80, 0x08, 0x00, 0x80, 0x08, 0x00, 0x80, 0x08, 0x00, 0x80, 0x08, // 61
-0x00, 0x00, 0x00, 0x40, 0x10, 0x00, 0x80, 0x08, 0x00, 0x80, 0x08, 0x00, 0x80, 0x08, 0x00, 0x00, 0x05, 0x00, 0x00, 0x05, 0x00, 0x00, 0x02, // 62
-0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x10, 0x00, 0x00, 0x08, 0x00, 0x00, 0x08, 0x5C, 0x00, 0x08, 0x02, 0x00, 0x10, 0x01, 0x00, 0xE0, // 63
-0x00, 0x00, 0x00, 0x00, 0x3F, 0x00, 0xC0, 0x40, 0x00, 0x20, 0x80, 0x00, 0x10, 0x1E, 0x01, 0x10, 0x21, 0x01, 0x88, 0x40, 0x02, 0x48, 0x40, 0x02, 0x48, 0x40, 0x02, 0x48, 0x20, 0x02, 0x88, 0x7C, 0x02, 0xC8, 0x43, 0x02, 0x10, 0x40, 0x02, 0x10, 0x20, 0x01, 0x60, 0x10, 0x01, 0x80, 0x8F, // 64
-0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x1C, 0x00, 0x80, 0x07, 0x00, 0x70, 0x04, 0x00, 0x08, 0x04, 0x00, 0x70, 0x04, 0x00, 0x80, 0x07, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x60, // 65
-0x00, 0x00, 0x00, 0xF8, 0x7F, 0x00, 0x08, 0x41, 0x00, 0x08, 0x41, 0x00, 0x08, 0x41, 0x00, 0x08, 0x41, 0x00, 0x08, 0x41, 0x00, 0x08, 0x41, 0x00, 0x90, 0x22, 0x00, 0x60, 0x1C, // 66
-0x00, 0x00, 0x00, 0xC0, 0x0F, 0x00, 0x20, 0x10, 0x00, 0x10, 0x20, 0x00, 0x08, 0x40, 0x00, 0x08, 0x40, 0x00, 0x08, 0x40, 0x00, 0x08, 0x40, 0x00, 0x08, 0x40, 0x00, 0x10, 0x20, 0x00, 0x20, 0x10, // 67
-0x00, 0x00, 0x00, 0xF8, 0x7F, 0x00, 0x08, 0x40, 0x00, 0x08, 0x40, 0x00, 0x08, 0x40, 0x00, 0x08, 0x40, 0x00, 0x08, 0x40, 0x00, 0x08, 0x40, 0x00, 0x10, 0x20, 0x00, 0x20, 0x10, 0x00, 0xC0, 0x0F, // 68
-0x00, 0x00, 0x00, 0xF8, 0x7F, 0x00, 0x08, 0x41, 0x00, 0x08, 0x41, 0x00, 0x08, 0x41, 0x00, 0x08, 0x41, 0x00, 0x08, 0x41, 0x00, 0x08, 0x41, 0x00, 0x08, 0x41, 0x00, 0x08, 0x40, // 69
-0x00, 0x00, 0x00, 0xF8, 0x7F, 0x00, 0x08, 0x02, 0x00, 0x08, 0x02, 0x00, 0x08, 0x02, 0x00, 0x08, 0x02, 0x00, 0x08, 0x02, 0x00, 0x08, 0x02, 0x00, 0x08, // 70
-0x00, 0x00, 0x00, 0xC0, 0x0F, 0x00, 0x20, 0x10, 0x00, 0x10, 0x20, 0x00, 0x08, 0x40, 0x00, 0x08, 0x40, 0x00, 0x08, 0x42, 0x00, 0x08, 0x42, 0x00, 0x10, 0x22, 0x00, 0x20, 0x12, 0x00, 0x00, 0x0E, // 71
-0x00, 0x00, 0x00, 0xF8, 0x7F, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0xF8, 0x7F, // 72
-0x00, 0x00, 0x00, 0xF8, 0x7F, // 73
-0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x40, 0x00, 0x00, 0x40, 0x00, 0x00, 0x40, 0x00, 0x00, 0x40, 0x00, 0xF8, 0x3F, // 74
-0x00, 0x00, 0x00, 0xF8, 0x7F, 0x00, 0x00, 0x04, 0x00, 0x00, 0x02, 0x00, 0x00, 0x01, 0x00, 0x80, 0x03, 0x00, 0x40, 0x04, 0x00, 0x20, 0x18, 0x00, 0x10, 0x20, 0x00, 0x08, 0x40, // 75
-0x00, 0x00, 0x00, 0xF8, 0x7F, 0x00, 0x00, 0x40, 0x00, 0x00, 0x40, 0x00, 0x00, 0x40, 0x00, 0x00, 0x40, 0x00, 0x00, 0x40, 0x00, 0x00, 0x40, // 76
-0x00, 0x00, 0x00, 0xF8, 0x7F, 0x00, 0x30, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x60, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x03, 0x00, 0xC0, 0x00, 0x00, 0x30, 0x00, 0x00, 0xF8, 0x7F, // 77
-0x00, 0x00, 0x00, 0xF8, 0x7F, 0x00, 0x10, 0x00, 0x00, 0x60, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x04, 0x00, 0x00, 0x18, 0x00, 0x00, 0x20, 0x00, 0xF8, 0x7F, // 78
-0x00, 0x00, 0x00, 0xC0, 0x0F, 0x00, 0x20, 0x10, 0x00, 0x10, 0x20, 0x00, 0x08, 0x40, 0x00, 0x08, 0x40, 0x00, 0x08, 0x40, 0x00, 0x08, 0x40, 0x00, 0x10, 0x20, 0x00, 0x20, 0x10, 0x00, 0xC0, 0x0F, // 79
-0x00, 0x00, 0x00, 0xF8, 0x7F, 0x00, 0x08, 0x02, 0x00, 0x08, 0x02, 0x00, 0x08, 0x02, 0x00, 0x08, 0x02, 0x00, 0x08, 0x02, 0x00, 0x08, 0x02, 0x00, 0x10, 0x01, 0x00, 0xE0, // 80
-0x00, 0x00, 0x00, 0xC0, 0x0F, 0x00, 0x20, 0x10, 0x00, 0x10, 0x20, 0x00, 0x08, 0x40, 0x00, 0x08, 0x40, 0x00, 0x08, 0x50, 0x00, 0x08, 0x50, 0x00, 0x10, 0x20, 0x00, 0x20, 0x70, 0x00, 0xC0, 0x4F, // 81
-0x00, 0x00, 0x00, 0xF8, 0x7F, 0x00, 0x08, 0x02, 0x00, 0x08, 0x02, 0x00, 0x08, 0x02, 0x00, 0x08, 0x02, 0x00, 0x08, 0x06, 0x00, 0x08, 0x1A, 0x00, 0x10, 0x21, 0x00, 0xE0, 0x40, // 82
-0x00, 0x00, 0x00, 0x60, 0x10, 0x00, 0x90, 0x20, 0x00, 0x08, 0x41, 0x00, 0x08, 0x41, 0x00, 0x08, 0x41, 0x00, 0x08, 0x42, 0x00, 0x08, 0x42, 0x00, 0x10, 0x22, 0x00, 0x20, 0x1C, // 83
-0x08, 0x00, 0x00, 0x08, 0x00, 0x00, 0x08, 0x00, 0x00, 0x08, 0x00, 0x00, 0xF8, 0x7F, 0x00, 0x08, 0x00, 0x00, 0x08, 0x00, 0x00, 0x08, 0x00, 0x00, 0x08, // 84
-0x00, 0x00, 0x00, 0xF8, 0x1F, 0x00, 0x00, 0x20, 0x00, 0x00, 0x40, 0x00, 0x00, 0x40, 0x00, 0x00, 0x40, 0x00, 0x00, 0x40, 0x00, 0x00, 0x40, 0x00, 0x00, 0x20, 0x00, 0xF8, 0x1F, // 85
-0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0xE0, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x18, 0x00, 0x00, 0x60, 0x00, 0x00, 0x18, 0x00, 0x00, 0x07, 0x00, 0xE0, 0x00, 0x00, 0x18, // 86
-0x18, 0x00, 0x00, 0xE0, 0x01, 0x00, 0x00, 0x1E, 0x00, 0x00, 0x60, 0x00, 0x00, 0x1C, 0x00, 0x80, 0x03, 0x00, 0x70, 0x00, 0x00, 0x08, 0x00, 0x00, 0x70, 0x00, 0x00, 0x80, 0x03, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x60, 0x00, 0x00, 0x1E, 0x00, 0xE0, 0x01, 0x00, 0x18, // 87
-0x00, 0x40, 0x00, 0x08, 0x20, 0x00, 0x10, 0x10, 0x00, 0x60, 0x0C, 0x00, 0x80, 0x02, 0x00, 0x00, 0x01, 0x00, 0x80, 0x02, 0x00, 0x60, 0x0C, 0x00, 0x10, 0x10, 0x00, 0x08, 0x20, 0x00, 0x00, 0x40, // 88
-0x08, 0x00, 0x00, 0x30, 0x00, 0x00, 0x40, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x7E, 0x00, 0x80, 0x01, 0x00, 0x40, 0x00, 0x00, 0x30, 0x00, 0x00, 0x08, // 89
-0x00, 0x40, 0x00, 0x08, 0x60, 0x00, 0x08, 0x58, 0x00, 0x08, 0x44, 0x00, 0x08, 0x43, 0x00, 0x88, 0x40, 0x00, 0x68, 0x40, 0x00, 0x18, 0x40, 0x00, 0x08, 0x40, // 90
-0x00, 0x00, 0x00, 0xF8, 0xFF, 0x03, 0x08, 0x00, 0x02, 0x08, 0x00, 0x02, // 91
-0x18, 0x00, 0x00, 0xE0, 0x01, 0x00, 0x00, 0x1E, 0x00, 0x00, 0x60, // 92
-0x08, 0x00, 0x02, 0x08, 0x00, 0x02, 0xF8, 0xFF, 0x03, // 93
-0x00, 0x01, 0x00, 0xC0, 0x00, 0x00, 0x30, 0x00, 0x00, 0x08, 0x00, 0x00, 0x30, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0x01, // 94
-0x00, 0x00, 0x02, 0x00, 0x00, 0x02, 0x00, 0x00, 0x02, 0x00, 0x00, 0x02, 0x00, 0x00, 0x02, 0x00, 0x00, 0x02, 0x00, 0x00, 0x02, 0x00, 0x00, 0x02, 0x00, 0x00, 0x02, // 95
-0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x10, // 96
-0x00, 0x00, 0x00, 0x00, 0x39, 0x00, 0x80, 0x44, 0x00, 0x40, 0x44, 0x00, 0x40, 0x44, 0x00, 0x40, 0x42, 0x00, 0x40, 0x22, 0x00, 0x80, 0x7F, // 97
-0x00, 0x00, 0x00, 0xF8, 0x7F, 0x00, 0x80, 0x20, 0x00, 0x40, 0x40, 0x00, 0x40, 0x40, 0x00, 0x40, 0x40, 0x00, 0x80, 0x20, 0x00, 0x00, 0x1F, // 98
-0x00, 0x00, 0x00, 0x00, 0x1F, 0x00, 0x80, 0x20, 0x00, 0x40, 0x40, 0x00, 0x40, 0x40, 0x00, 0x40, 0x40, 0x00, 0x80, 0x20, // 99
-0x00, 0x00, 0x00, 0x00, 0x1F, 0x00, 0x80, 0x20, 0x00, 0x40, 0x40, 0x00, 0x40, 0x40, 0x00, 0x40, 0x40, 0x00, 0x80, 0x20, 0x00, 0xF8, 0x7F, // 100
-0x00, 0x00, 0x00, 0x00, 0x1F, 0x00, 0x80, 0x24, 0x00, 0x40, 0x44, 0x00, 0x40, 0x44, 0x00, 0x40, 0x44, 0x00, 0x80, 0x24, 0x00, 0x00, 0x17, // 101
-0x40, 0x00, 0x00, 0xF0, 0x7F, 0x00, 0x48, 0x00, 0x00, 0x48, // 102
-0x00, 0x00, 0x00, 0x00, 0x1F, 0x01, 0x80, 0x20, 0x02, 0x40, 0x40, 0x02, 0x40, 0x40, 0x02, 0x40, 0x40, 0x02, 0x80, 0x20, 0x01, 0xC0, 0xFF, // 103
-0x00, 0x00, 0x00, 0xF8, 0x7F, 0x00, 0x80, 0x00, 0x00, 0x40, 0x00, 0x00, 0x40, 0x00, 0x00, 0x40, 0x00, 0x00, 0x80, 0x7F, // 104
-0x00, 0x00, 0x00, 0xC8, 0x7F, // 105
-0x00, 0x00, 0x02, 0xC8, 0xFF, 0x01, // 106
-0x00, 0x00, 0x00, 0xF8, 0x7F, 0x00, 0x00, 0x08, 0x00, 0x00, 0x04, 0x00, 0x00, 0x06, 0x00, 0x00, 0x19, 0x00, 0x80, 0x20, 0x00, 0x40, 0x40, // 107
-0x00, 0x00, 0x00, 0xF8, 0x7F, // 108
-0x00, 0x00, 0x00, 0xC0, 0x7F, 0x00, 0x80, 0x00, 0x00, 0x40, 0x00, 0x00, 0x40, 0x00, 0x00, 0x40, 0x00, 0x00, 0x80, 0x7F, 0x00, 0x80, 0x00, 0x00, 0x40, 0x00, 0x00, 0x40, 0x00, 0x00, 0x40, 0x00, 0x00, 0x80, 0x7F, // 109
-0x00, 0x00, 0x00, 0xC0, 0x7F, 0x00, 0x80, 0x00, 0x00, 0x40, 0x00, 0x00, 0x40, 0x00, 0x00, 0x40, 0x00, 0x00, 0x80, 0x7F, // 110
-0x00, 0x00, 0x00, 0x00, 0x1F, 0x00, 0x80, 0x20, 0x00, 0x40, 0x40, 0x00, 0x40, 0x40, 0x00, 0x40, 0x40, 0x00, 0x80, 0x20, 0x00, 0x00, 0x1F, // 111
-0x00, 0x00, 0x00, 0xC0, 0xFF, 0x03, 0x80, 0x20, 0x00, 0x40, 0x40, 0x00, 0x40, 0x40, 0x00, 0x40, 0x40, 0x00, 0x80, 0x20, 0x00, 0x00, 0x1F, // 112
-0x00, 0x00, 0x00, 0x00, 0x1F, 0x00, 0x80, 0x20, 0x00, 0x40, 0x40, 0x00, 0x40, 0x40, 0x00, 0x40, 0x40, 0x00, 0x80, 0x20, 0x00, 0xC0, 0xFF, 0x03, // 113
-0x00, 0x00, 0x00, 0xC0, 0x7F, 0x00, 0x80, 0x00, 0x00, 0x40, 0x00, 0x00, 0x40, // 114
-0x00, 0x00, 0x00, 0x80, 0x23, 0x00, 0x40, 0x44, 0x00, 0x40, 0x44, 0x00, 0x40, 0x44, 0x00, 0x40, 0x44, 0x00, 0x80, 0x38, // 115
-0x40, 0x00, 0x00, 0xF0, 0x7F, 0x00, 0x40, 0x40, 0x00, 0x40, 0x40, // 116
-0x00, 0x00, 0x00, 0xC0, 0x3F, 0x00, 0x00, 0x40, 0x00, 0x00, 0x40, 0x00, 0x00, 0x40, 0x00, 0x00, 0x20, 0x00, 0xC0, 0x7F, // 117
-0xC0, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x60, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x03, 0x00, 0xC0, // 118
-0xC0, 0x00, 0x00, 0x00, 0x1F, 0x00, 0x00, 0x60, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x03, 0x00, 0xC0, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x60, 0x00, 0x00, 0x1F, 0x00, 0xC0, // 119
-0x40, 0x40, 0x00, 0x80, 0x20, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x04, 0x00, 0x00, 0x1B, 0x00, 0x80, 0x20, 0x00, 0x40, 0x40, // 120
-0xC0, 0x01, 0x00, 0x00, 0x06, 0x02, 0x00, 0x38, 0x02, 0x00, 0xE0, 0x01, 0x00, 0x38, 0x00, 0x00, 0x07, 0x00, 0xC0, // 121
-0x40, 0x40, 0x00, 0x40, 0x60, 0x00, 0x40, 0x58, 0x00, 0x40, 0x44, 0x00, 0x40, 0x43, 0x00, 0xC0, 0x40, 0x00, 0x40, 0x40, // 122
-0x00, 0x04, 0x00, 0x00, 0x04, 0x00, 0xF0, 0xFB, 0x01, 0x08, 0x00, 0x02, 0x08, 0x00, 0x02, // 123
-0x00, 0x00, 0x00, 0xF8, 0xFF, 0x03, // 124
-0x08, 0x00, 0x02, 0x08, 0x00, 0x02, 0xF0, 0xFB, 0x01, 0x00, 0x04, 0x00, 0x00, 0x04, // 125
-0x00, 0x02, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x02, 0x00, 0x00, 0x02, 0x00, 0x00, 0x02, 0x00, 0x00, 0x01, // 126
-0x00, 0x00, 0x00, 0xF8, 0x7F, 0x00, 0x00, 0x42, 0x00, 0x00, 0x41, 0x00, 0x80, 0x40, 0x00, 0x00, 0x40, 0x00, 0x00, 0x40, 0x00, 0x00, 0x40, // 129
-0x00, 0x01, 0x00, 0xF8, 0x7F, 0x00, 0x80, // 130
-0x00, 0x00, 0x00, 0xF8, 0x7F, 0x00, 0x10, 0x00, 0x00, 0x60, 0x00, 0x00, 0x80, 0x00, 0x00, 0x08, 0x03, 0x00, 0x04, 0x04, 0x00, 0x02, 0x18, 0x00, 0x00, 0x20, 0x00, 0xF8, 0x7F, // 131
-0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x1C, 0x00, 0x80, 0x07, 0x00, 0x70, 0x04, 0x00, 0x08, 0x04, 0x00, 0x70, 0x04, 0x00, 0x80, 0x07, 0x00, 0x00, 0x9C, 0x01, 0x00, 0x60, 0x02, // 132
-0x00, 0x00, 0x00, 0x00, 0x39, 0x00, 0x80, 0x44, 0x00, 0x40, 0x44, 0x00, 0x40, 0x44, 0x00, 0x40, 0x42, 0x00, 0x40, 0x22, 0x00, 0x80, 0x7F, 0x03, 0x00, 0x80, 0x04, // 133
-0x00, 0x00, 0x00, 0xC0, 0x0F, 0x00, 0x20, 0x10, 0x00, 0x10, 0x20, 0x00, 0x08, 0x40, 0x00, 0x08, 0x40, 0x00, 0x08, 0x40, 0x00, 0x0A, 0x40, 0x00, 0x09, 0x40, 0x00, 0x10, 0x20, 0x00, 0x20, 0x10, // 134
-0x00, 0x00, 0x00, 0x00, 0x1F, 0x00, 0x80, 0x20, 0x00, 0x40, 0x40, 0x00, 0x50, 0x40, 0x00, 0x48, 0x40, 0x00, 0x80, 0x20, // 135
-0x00, 0x00, 0x00, 0xC0, 0x7F, 0x00, 0x80, 0x00, 0x00, 0x40, 0x00, 0x00, 0x50, 0x00, 0x00, 0x48, 0x00, 0x00, 0x80, 0x7F, // 136
-0x40, 0x40, 0x00, 0x40, 0x60, 0x00, 0x40, 0x58, 0x00, 0x50, 0x44, 0x00, 0x48, 0x43, 0x00, 0xC0, 0x40, 0x00, 0x40, 0x40, // 137
-0x00, 0x00, 0x00, 0xC0, 0x0F, 0x00, 0x20, 0x10, 0x00, 0x10, 0x20, 0x00, 0x08, 0x40, 0x00, 0x08, 0x40, 0x00, 0x0A, 0x40, 0x00, 0x09, 0x40, 0x00, 0x10, 0x20, 0x00, 0x20, 0x10, 0x00, 0xC0, 0x0F, // 147
-0x00, 0x00, 0x00, 0x00, 0x1F, 0x00, 0x80, 0x20, 0x00, 0x40, 0x40, 0x00, 0x50, 0x40, 0x00, 0x48, 0x40, 0x00, 0x80, 0x20, 0x00, 0x00, 0x1F, // 148
-0x00, 0x00, 0x00, 0xF8, 0x7F, 0x00, 0x08, 0x41, 0x00, 0x08, 0x41, 0x00, 0x08, 0x41, 0x00, 0x08, 0x41, 0x00, 0x08, 0xC1, 0x01, 0x08, 0x41, 0x02, 0x08, 0x41, 0x00, 0x08, 0x40, // 152
-0x00, 0x00, 0x00, 0x00, 0x1F, 0x00, 0x80, 0x24, 0x00, 0x40, 0x44, 0x00, 0x40, 0x44, 0x03, 0x40, 0xC4, 0x04, 0x80, 0x24, 0x00, 0x00, 0x17, // 153
-0x00, 0x00, 0x00, 0x60, 0x10, 0x00, 0x90, 0x20, 0x00, 0x08, 0x41, 0x00, 0x08, 0x41, 0x00, 0x0A, 0x41, 0x00, 0x09, 0x42, 0x00, 0x08, 0x42, 0x00, 0x10, 0x22, 0x00, 0x20, 0x1C, // 154
-0x00, 0x00, 0x00, 0x80, 0x23, 0x00, 0x40, 0x44, 0x00, 0x40, 0x44, 0x00, 0x50, 0x44, 0x00, 0x48, 0x44, 0x00, 0x80, 0x38, // 155
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0xFF, 0x03, // 161
-0x00, 0x00, 0x00, 0x00, 0x1F, 0x00, 0x80, 0x20, 0x03, 0x40, 0xF0, 0x00, 0x40, 0x4E, 0x00, 0xC0, 0x41, 0x00, 0xB8, 0x20, 0x00, 0x00, 0x11, // 162
-0x00, 0x41, 0x00, 0xE0, 0x31, 0x00, 0x10, 0x2F, 0x00, 0x08, 0x21, 0x00, 0x08, 0x21, 0x00, 0x08, 0x40, 0x00, 0x10, 0x40, 0x00, 0x20, 0x20, // 163
-0x00, 0x00, 0x00, 0x40, 0x0B, 0x00, 0x80, 0x04, 0x00, 0x40, 0x08, 0x00, 0x40, 0x08, 0x00, 0x80, 0x04, 0x00, 0x40, 0x0B, // 164
-0x08, 0x0A, 0x00, 0x10, 0x0A, 0x00, 0x60, 0x0A, 0x00, 0x80, 0x0B, 0x00, 0x00, 0x7E, 0x00, 0x80, 0x0B, 0x00, 0x60, 0x0A, 0x00, 0x10, 0x0A, 0x00, 0x08, 0x0A, // 165
-0x00, 0x00, 0x00, 0xF8, 0xF1, 0x03, // 166
-0x00, 0x86, 0x00, 0x70, 0x09, 0x01, 0xC8, 0x10, 0x02, 0x88, 0x10, 0x02, 0x08, 0x21, 0x02, 0x08, 0x61, 0x02, 0x30, 0xD2, 0x01, 0x00, 0x0C, // 167
-0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, // 168
-0xC0, 0x0F, 0x00, 0x20, 0x10, 0x00, 0x10, 0x20, 0x00, 0xC8, 0x47, 0x00, 0x28, 0x48, 0x00, 0x28, 0x48, 0x00, 0x28, 0x48, 0x00, 0x28, 0x48, 0x00, 0x48, 0x44, 0x00, 0x10, 0x20, 0x00, 0x20, 0x10, 0x00, 0xC0, 0x0F, // 169
-0xD0, 0x00, 0x00, 0x48, 0x01, 0x00, 0x28, 0x01, 0x00, 0x28, 0x01, 0x00, 0xF0, 0x01, // 170
-0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x1B, 0x00, 0x80, 0x20, 0x00, 0x00, 0x04, 0x00, 0x00, 0x1B, 0x00, 0x80, 0x20, // 171
-0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x80, 0x00, 0x00, 0x80, 0x00, 0x00, 0x80, 0x00, 0x00, 0x80, 0x00, 0x00, 0x80, 0x00, 0x00, 0x80, 0x0F, // 172
-0x00, 0x08, 0x00, 0x00, 0x08, 0x00, 0x00, 0x08, 0x00, 0x00, 0x08, // 173
-0xC0, 0x0F, 0x00, 0x20, 0x10, 0x00, 0x10, 0x20, 0x00, 0xE8, 0x4F, 0x00, 0x28, 0x41, 0x00, 0x28, 0x41, 0x00, 0x28, 0x43, 0x00, 0x28, 0x45, 0x00, 0xC8, 0x48, 0x00, 0x10, 0x20, 0x00, 0x20, 0x10, 0x00, 0xC0, 0x0F, // 174
-0x04, 0x00, 0x00, 0x04, 0x00, 0x00, 0x04, 0x00, 0x00, 0x04, 0x00, 0x00, 0x04, 0x00, 0x00, 0x04, 0x00, 0x00, 0x04, 0x00, 0x00, 0x04, 0x00, 0x00, 0x04, // 175
-0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x48, 0x00, 0x00, 0x48, 0x00, 0x00, 0x30, // 176
-0x00, 0x00, 0x00, 0x00, 0x41, 0x00, 0x00, 0x41, 0x00, 0x00, 0x41, 0x00, 0xE0, 0x4F, 0x00, 0x00, 0x41, 0x00, 0x00, 0x41, 0x00, 0x00, 0x41, // 177
-0x10, 0x01, 0x00, 0x88, 0x01, 0x00, 0x48, 0x01, 0x00, 0x48, 0x01, 0x00, 0x30, 0x01, // 178
-0x90, 0x00, 0x00, 0x08, 0x01, 0x00, 0x08, 0x01, 0x00, 0x28, 0x01, 0x00, 0xD8, // 179
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x08, // 180
-0x00, 0x00, 0x00, 0xC0, 0xFF, 0x03, 0x00, 0x20, 0x00, 0x00, 0x40, 0x00, 0x00, 0x40, 0x00, 0x00, 0x40, 0x00, 0x00, 0x20, 0x00, 0xC0, 0x7F, // 181
-0xF0, 0x00, 0x00, 0xF8, 0x00, 0x00, 0xF8, 0x01, 0x00, 0xF8, 0x01, 0x00, 0xF8, 0xFF, 0x03, 0x08, 0x00, 0x00, 0x08, 0x00, 0x00, 0xF8, 0xFF, 0x03, 0x08, // 182
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, // 183
-0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x80, 0x02, 0x00, 0x00, 0x03, // 184
-0x00, 0x40, 0x00, 0x08, 0x60, 0x00, 0x08, 0x58, 0x00, 0x08, 0x44, 0x00, 0x0A, 0x43, 0x00, 0x89, 0x40, 0x00, 0x68, 0x40, 0x00, 0x18, 0x40, 0x00, 0x08, 0x40, // 185
-0xF0, 0x00, 0x00, 0x08, 0x01, 0x00, 0x08, 0x01, 0x00, 0x08, 0x01, 0x00, 0xF0, // 186
-0x00, 0x40, 0x00, 0x08, 0x60, 0x00, 0x08, 0x58, 0x00, 0x08, 0x44, 0x00, 0x0A, 0x43, 0x00, 0x88, 0x40, 0x00, 0x68, 0x40, 0x00, 0x18, 0x40, 0x00, 0x08, 0x40, // 187
-0x40, 0x40, 0x00, 0x40, 0x60, 0x00, 0x40, 0x58, 0x00, 0x50, 0x44, 0x00, 0x40, 0x43, 0x00, 0xC0, 0x40, 0x00, 0x40, 0x40, // 188
-0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x08, 0x40, 0x00, 0xF8, 0x31, 0x00, 0x00, 0x08, 0x00, 0x00, 0x04, 0x00, 0x00, 0x03, 0x00, 0x80, 0x00, 0x00, 0x60, 0x44, 0x00, 0x10, 0x62, 0x00, 0x08, 0x52, 0x00, 0x00, 0x52, 0x00, 0x00, 0x4C, // 189
-0x90, 0x00, 0x00, 0x08, 0x01, 0x00, 0x08, 0x41, 0x00, 0x28, 0x21, 0x00, 0xD8, 0x18, 0x00, 0x00, 0x04, 0x00, 0x00, 0x03, 0x00, 0x80, 0x00, 0x00, 0x40, 0x30, 0x00, 0x30, 0x28, 0x00, 0x08, 0x24, 0x00, 0x00, 0x7E, 0x00, 0x00, 0x20, // 190
-0x00, 0x00, 0x00, 0x00, 0xE0, 0x00, 0x00, 0x10, 0x01, 0x00, 0x08, 0x02, 0x40, 0x07, 0x02, 0x00, 0x00, 0x02, 0x00, 0x00, 0x02, 0x00, 0x00, 0x01, 0x00, 0xC0, // 191
-0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x1C, 0x00, 0x80, 0x07, 0x00, 0x71, 0x04, 0x00, 0x0A, 0x04, 0x00, 0x70, 0x04, 0x00, 0x80, 0x07, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x60, // 192
-0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x1C, 0x00, 0x80, 0x07, 0x00, 0x70, 0x04, 0x00, 0x0A, 0x04, 0x00, 0x71, 0x04, 0x00, 0x80, 0x07, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x60, // 193
-0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x1C, 0x00, 0x80, 0x07, 0x00, 0x72, 0x04, 0x00, 0x09, 0x04, 0x00, 0x71, 0x04, 0x00, 0x82, 0x07, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x60, // 194
-0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x1C, 0x00, 0x80, 0x07, 0x00, 0x72, 0x04, 0x00, 0x09, 0x04, 0x00, 0x72, 0x04, 0x00, 0x81, 0x07, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x60, // 195
-0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x1C, 0x00, 0x80, 0x07, 0x00, 0x72, 0x04, 0x00, 0x08, 0x04, 0x00, 0x72, 0x04, 0x00, 0x80, 0x07, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x60, // 196
-0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x1C, 0x00, 0x80, 0x07, 0x00, 0x7E, 0x04, 0x00, 0x0A, 0x04, 0x00, 0x7E, 0x04, 0x00, 0x80, 0x07, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x60, // 197
-0x00, 0x60, 0x00, 0x00, 0x18, 0x00, 0x00, 0x06, 0x00, 0x80, 0x05, 0x00, 0x60, 0x04, 0x00, 0x18, 0x04, 0x00, 0x08, 0x04, 0x00, 0x08, 0x04, 0x00, 0xF8, 0x7F, 0x00, 0x08, 0x41, 0x00, 0x08, 0x41, 0x00, 0x08, 0x41, 0x00, 0x08, 0x41, 0x00, 0x08, 0x41, 0x00, 0x08, 0x41, // 198
-0x00, 0x00, 0x00, 0xC0, 0x0F, 0x00, 0x20, 0x10, 0x00, 0x10, 0x20, 0x00, 0x08, 0x40, 0x00, 0x08, 0x40, 0x02, 0x08, 0xC0, 0x02, 0x08, 0x40, 0x03, 0x08, 0x40, 0x00, 0x10, 0x20, 0x00, 0x20, 0x10, // 199
-0x00, 0x00, 0x00, 0xF8, 0x7F, 0x00, 0x08, 0x41, 0x00, 0x08, 0x41, 0x00, 0x08, 0x41, 0x00, 0x09, 0x41, 0x00, 0x0A, 0x41, 0x00, 0x08, 0x41, 0x00, 0x08, 0x41, 0x00, 0x08, 0x40, // 200
-0x00, 0x00, 0x00, 0xF8, 0x7F, 0x00, 0x08, 0x41, 0x00, 0x08, 0x41, 0x00, 0x08, 0x41, 0x00, 0x0A, 0x41, 0x00, 0x09, 0x41, 0x00, 0x08, 0x41, 0x00, 0x08, 0x41, 0x00, 0x08, 0x40, // 201
-0x00, 0x00, 0x00, 0xF8, 0x7F, 0x00, 0x08, 0x41, 0x00, 0x08, 0x41, 0x00, 0x0A, 0x41, 0x00, 0x09, 0x41, 0x00, 0x09, 0x41, 0x00, 0x0A, 0x41, 0x00, 0x08, 0x41, 0x00, 0x08, 0x40, // 202
-0x00, 0x00, 0x00, 0xF8, 0x7F, 0x00, 0x08, 0x41, 0x00, 0x08, 0x41, 0x00, 0x0A, 0x41, 0x00, 0x08, 0x41, 0x00, 0x0A, 0x41, 0x00, 0x08, 0x41, 0x00, 0x08, 0x41, 0x00, 0x08, 0x40, // 203
-0x01, 0x00, 0x00, 0xFA, 0x7F, // 204
-0x00, 0x00, 0x00, 0xFA, 0x7F, 0x00, 0x01, // 205
-0x02, 0x00, 0x00, 0xF9, 0x7F, 0x00, 0x01, 0x00, 0x00, 0x02, // 206
-0x02, 0x00, 0x00, 0xF8, 0x7F, 0x00, 0x02, // 207
-0x00, 0x02, 0x00, 0xF8, 0x7F, 0x00, 0x08, 0x42, 0x00, 0x08, 0x42, 0x00, 0x08, 0x42, 0x00, 0x08, 0x42, 0x00, 0x08, 0x40, 0x00, 0x08, 0x40, 0x00, 0x10, 0x20, 0x00, 0x20, 0x10, 0x00, 0xC0, 0x0F, // 208
-0x00, 0x00, 0x00, 0xF8, 0x7F, 0x00, 0x10, 0x00, 0x00, 0x60, 0x00, 0x00, 0x82, 0x00, 0x00, 0x01, 0x03, 0x00, 0x02, 0x04, 0x00, 0x01, 0x18, 0x00, 0x00, 0x20, 0x00, 0xF8, 0x7F, // 209
-0x00, 0x00, 0x00, 0xC0, 0x0F, 0x00, 0x20, 0x10, 0x00, 0x10, 0x20, 0x00, 0x08, 0x40, 0x00, 0x09, 0x40, 0x00, 0x0A, 0x40, 0x00, 0x08, 0x40, 0x00, 0x10, 0x20, 0x00, 0x20, 0x10, 0x00, 0xC0, 0x0F, // 210
-0x00, 0x00, 0x00, 0xC0, 0x0F, 0x00, 0x20, 0x10, 0x00, 0x10, 0x20, 0x00, 0x08, 0x40, 0x00, 0x0A, 0x40, 0x00, 0x09, 0x40, 0x00, 0x08, 0x40, 0x00, 0x10, 0x20, 0x00, 0x20, 0x10, 0x00, 0xC0, 0x0F, // 211
-0x00, 0x00, 0x00, 0xC0, 0x0F, 0x00, 0x20, 0x10, 0x00, 0x10, 0x20, 0x00, 0x0A, 0x40, 0x00, 0x09, 0x40, 0x00, 0x09, 0x40, 0x00, 0x0A, 0x40, 0x00, 0x10, 0x20, 0x00, 0x20, 0x10, 0x00, 0xC0, 0x0F, // 212
-0x00, 0x00, 0x00, 0xC0, 0x0F, 0x00, 0x20, 0x10, 0x00, 0x10, 0x20, 0x00, 0x0A, 0x40, 0x00, 0x09, 0x40, 0x00, 0x0A, 0x40, 0x00, 0x09, 0x40, 0x00, 0x10, 0x20, 0x00, 0x20, 0x10, 0x00, 0xC0, 0x0F, // 213
-0x00, 0x00, 0x00, 0xC0, 0x0F, 0x00, 0x20, 0x10, 0x00, 0x10, 0x20, 0x00, 0x08, 0x40, 0x00, 0x0A, 0x40, 0x00, 0x08, 0x40, 0x00, 0x0A, 0x40, 0x00, 0x10, 0x20, 0x00, 0x20, 0x10, 0x00, 0xC0, 0x0F, // 214
-0x00, 0x00, 0x00, 0x40, 0x10, 0x00, 0x80, 0x08, 0x00, 0x00, 0x05, 0x00, 0x00, 0x07, 0x00, 0x00, 0x05, 0x00, 0x80, 0x08, 0x00, 0x40, 0x10, // 215
-0x00, 0x00, 0x00, 0xC0, 0x4F, 0x00, 0x20, 0x30, 0x00, 0x10, 0x30, 0x00, 0x08, 0x4C, 0x00, 0x08, 0x42, 0x00, 0x08, 0x41, 0x00, 0xC8, 0x40, 0x00, 0x30, 0x20, 0x00, 0x30, 0x10, 0x00, 0xC8, 0x0F, // 216
-0x00, 0x00, 0x00, 0xF8, 0x1F, 0x00, 0x00, 0x20, 0x00, 0x00, 0x40, 0x00, 0x01, 0x40, 0x00, 0x02, 0x40, 0x00, 0x00, 0x40, 0x00, 0x00, 0x40, 0x00, 0x00, 0x20, 0x00, 0xF8, 0x1F, // 217
-0x00, 0x00, 0x00, 0xF8, 0x1F, 0x00, 0x00, 0x20, 0x00, 0x00, 0x40, 0x00, 0x00, 0x40, 0x00, 0x02, 0x40, 0x00, 0x01, 0x40, 0x00, 0x00, 0x40, 0x00, 0x00, 0x20, 0x00, 0xF8, 0x1F, // 218
-0x00, 0x00, 0x00, 0xF8, 0x1F, 0x00, 0x00, 0x20, 0x00, 0x00, 0x40, 0x00, 0x02, 0x40, 0x00, 0x01, 0x40, 0x00, 0x01, 0x40, 0x00, 0x02, 0x40, 0x00, 0x00, 0x20, 0x00, 0xF8, 0x1F, // 219
-0x00, 0x00, 0x00, 0xF8, 0x1F, 0x00, 0x00, 0x20, 0x00, 0x00, 0x40, 0x00, 0x02, 0x40, 0x00, 0x00, 0x40, 0x00, 0x02, 0x40, 0x00, 0x00, 0x40, 0x00, 0x00, 0x20, 0x00, 0xF8, 0x1F, // 220
-0x08, 0x00, 0x00, 0x30, 0x00, 0x00, 0x40, 0x00, 0x00, 0x80, 0x01, 0x00, 0x02, 0x7E, 0x00, 0x81, 0x01, 0x00, 0x40, 0x00, 0x00, 0x30, 0x00, 0x00, 0x08, // 221
-0x00, 0x00, 0x00, 0xF8, 0x7F, 0x00, 0x20, 0x10, 0x00, 0x20, 0x10, 0x00, 0x20, 0x10, 0x00, 0x20, 0x10, 0x00, 0x20, 0x10, 0x00, 0x20, 0x10, 0x00, 0x40, 0x08, 0x00, 0x80, 0x07, // 222
-0x00, 0x00, 0x00, 0xE0, 0x7F, 0x00, 0x10, 0x00, 0x00, 0x08, 0x20, 0x00, 0x88, 0x43, 0x00, 0x70, 0x42, 0x00, 0x00, 0x44, 0x00, 0x00, 0x38, // 223
-0x00, 0x00, 0x00, 0x00, 0x39, 0x00, 0x80, 0x44, 0x00, 0x40, 0x44, 0x00, 0x48, 0x44, 0x00, 0x50, 0x42, 0x00, 0x40, 0x22, 0x00, 0x80, 0x7F, // 224
-0x00, 0x00, 0x00, 0x00, 0x39, 0x00, 0x80, 0x44, 0x00, 0x40, 0x44, 0x00, 0x50, 0x44, 0x00, 0x48, 0x42, 0x00, 0x40, 0x22, 0x00, 0x80, 0x7F, // 225
-0x00, 0x00, 0x00, 0x00, 0x39, 0x00, 0x80, 0x44, 0x00, 0x50, 0x44, 0x00, 0x48, 0x44, 0x00, 0x48, 0x42, 0x00, 0x50, 0x22, 0x00, 0x80, 0x7F, // 226
-0x00, 0x00, 0x00, 0x00, 0x39, 0x00, 0x80, 0x44, 0x00, 0x50, 0x44, 0x00, 0x48, 0x44, 0x00, 0x50, 0x42, 0x00, 0x48, 0x22, 0x00, 0x80, 0x7F, // 227
-0x00, 0x00, 0x00, 0x00, 0x39, 0x00, 0x80, 0x44, 0x00, 0x50, 0x44, 0x00, 0x40, 0x44, 0x00, 0x50, 0x42, 0x00, 0x40, 0x22, 0x00, 0x80, 0x7F, // 228
-0x00, 0x00, 0x00, 0x00, 0x39, 0x00, 0x80, 0x44, 0x00, 0x5C, 0x44, 0x00, 0x54, 0x44, 0x00, 0x5C, 0x42, 0x00, 0x40, 0x22, 0x00, 0x80, 0x7F, // 229
-0x00, 0x00, 0x00, 0x00, 0x39, 0x00, 0x80, 0x44, 0x00, 0x40, 0x44, 0x00, 0x40, 0x44, 0x00, 0x40, 0x42, 0x00, 0x40, 0x22, 0x00, 0x80, 0x3F, 0x00, 0x80, 0x24, 0x00, 0x40, 0x44, 0x00, 0x40, 0x44, 0x00, 0x40, 0x44, 0x00, 0x80, 0x24, 0x00, 0x00, 0x17, // 230
-0x00, 0x00, 0x00, 0x00, 0x1F, 0x00, 0x80, 0x20, 0x00, 0x40, 0x40, 0x02, 0x40, 0xC0, 0x02, 0x40, 0x40, 0x03, 0x80, 0x20, // 231
-0x00, 0x00, 0x00, 0x00, 0x1F, 0x00, 0x80, 0x24, 0x00, 0x48, 0x44, 0x00, 0x50, 0x44, 0x00, 0x40, 0x44, 0x00, 0x80, 0x24, 0x00, 0x00, 0x17, // 232
-0x00, 0x00, 0x00, 0x00, 0x1F, 0x00, 0x80, 0x24, 0x00, 0x40, 0x44, 0x00, 0x50, 0x44, 0x00, 0x48, 0x44, 0x00, 0x80, 0x24, 0x00, 0x00, 0x17, // 233
-0x00, 0x00, 0x00, 0x00, 0x1F, 0x00, 0x80, 0x24, 0x00, 0x50, 0x44, 0x00, 0x48, 0x44, 0x00, 0x48, 0x44, 0x00, 0x90, 0x24, 0x00, 0x00, 0x17, // 234
-0x00, 0x00, 0x00, 0x00, 0x1F, 0x00, 0x80, 0x24, 0x00, 0x50, 0x44, 0x00, 0x40, 0x44, 0x00, 0x50, 0x44, 0x00, 0x80, 0x24, 0x00, 0x00, 0x17, // 235
-0x08, 0x00, 0x00, 0xD0, 0x7F, // 236
-0x00, 0x00, 0x00, 0xD0, 0x7F, 0x00, 0x08, // 237
-0x10, 0x00, 0x00, 0xC8, 0x7F, 0x00, 0x08, 0x00, 0x00, 0x10, // 238
-0x10, 0x00, 0x00, 0xC0, 0x7F, 0x00, 0x10, // 239
-0x00, 0x00, 0x00, 0x00, 0x1F, 0x00, 0xA0, 0x20, 0x00, 0x68, 0x40, 0x00, 0x58, 0x40, 0x00, 0x70, 0x40, 0x00, 0xE8, 0x20, 0x00, 0x00, 0x1F, // 240
-0x00, 0x00, 0x00, 0xC0, 0x7F, 0x00, 0x90, 0x00, 0x00, 0x48, 0x00, 0x00, 0x50, 0x00, 0x00, 0x48, 0x00, 0x00, 0x80, 0x7F, // 241
-0x00, 0x00, 0x00, 0x00, 0x1F, 0x00, 0x80, 0x20, 0x00, 0x48, 0x40, 0x00, 0x50, 0x40, 0x00, 0x40, 0x40, 0x00, 0x80, 0x20, 0x00, 0x00, 0x1F, // 242
-0x00, 0x00, 0x00, 0x00, 0x1F, 0x00, 0x80, 0x20, 0x00, 0x40, 0x40, 0x00, 0x50, 0x40, 0x00, 0x48, 0x40, 0x00, 0x80, 0x20, 0x00, 0x00, 0x1F, // 243
-0x00, 0x00, 0x00, 0x00, 0x1F, 0x00, 0x80, 0x20, 0x00, 0x50, 0x40, 0x00, 0x48, 0x40, 0x00, 0x48, 0x40, 0x00, 0x90, 0x20, 0x00, 0x00, 0x1F, // 244
-0x00, 0x00, 0x00, 0x00, 0x1F, 0x00, 0x80, 0x20, 0x00, 0x50, 0x40, 0x00, 0x48, 0x40, 0x00, 0x50, 0x40, 0x00, 0x88, 0x20, 0x00, 0x00, 0x1F, // 245
-0x00, 0x00, 0x00, 0x00, 0x1F, 0x00, 0x80, 0x20, 0x00, 0x50, 0x40, 0x00, 0x40, 0x40, 0x00, 0x50, 0x40, 0x00, 0x80, 0x20, 0x00, 0x00, 0x1F, // 246
-0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x02, 0x00, 0x00, 0x02, 0x00, 0x80, 0x0A, 0x00, 0x00, 0x02, 0x00, 0x00, 0x02, 0x00, 0x00, 0x02, // 247
-0x00, 0x00, 0x00, 0x00, 0x5F, 0x00, 0x80, 0x30, 0x00, 0x40, 0x48, 0x00, 0x40, 0x44, 0x00, 0x40, 0x42, 0x00, 0x80, 0x21, 0x00, 0x40, 0x1F, // 248
-0x00, 0x00, 0x00, 0xC0, 0x3F, 0x00, 0x00, 0x40, 0x00, 0x08, 0x40, 0x00, 0x10, 0x40, 0x00, 0x00, 0x20, 0x00, 0xC0, 0x7F, // 249
-0x00, 0x00, 0x00, 0xC0, 0x3F, 0x00, 0x00, 0x40, 0x00, 0x00, 0x40, 0x00, 0x10, 0x40, 0x00, 0x08, 0x20, 0x00, 0xC0, 0x7F, // 250
-0x00, 0x00, 0x00, 0xC0, 0x3F, 0x00, 0x10, 0x40, 0x00, 0x08, 0x40, 0x00, 0x08, 0x40, 0x00, 0x10, 0x20, 0x00, 0xC0, 0x7F, // 251
-0x00, 0x00, 0x00, 0xD0, 0x3F, 0x00, 0x00, 0x40, 0x00, 0x10, 0x40, 0x00, 0x00, 0x40, 0x00, 0x00, 0x20, 0x00, 0xC0, 0x7F, // 252
-0xC0, 0x01, 0x00, 0x00, 0x06, 0x02, 0x00, 0x38, 0x02, 0x10, 0xE0, 0x01, 0x08, 0x38, 0x00, 0x00, 0x07, 0x00, 0xC0, // 253
-0x00, 0x00, 0x00, 0xF8, 0xFF, 0x03, 0x80, 0x20, 0x00, 0x40, 0x40, 0x00, 0x40, 0x40, 0x00, 0x40, 0x40, 0x00, 0x80, 0x20, 0x00, 0x00, 0x1F, // 254
-0xC0, 0x01, 0x00, 0x00, 0x06, 0x02, 0x10, 0x38, 0x02, 0x00, 0xE0, 0x01, 0x10, 0x38, 0x00, 0x00, 0x07, 0x00, 0xC0, // 255
+ 0x10, // Width: 16
+ 0x13, // Height: 19
+ 0x20, // First char: 32
+ 0xE0, // Number of chars: 224
+ // Jump Table:
+ 0xFF, 0xFF, 0x00, 0x04, // 32
+ 0x00, 0x00, 0x08, 0x04, // 33
+ 0x00, 0x08, 0x0D, 0x06, // 34
+ 0x00, 0x15, 0x1A, 0x0A, // 35
+ 0x00, 0x2F, 0x17, 0x09, // 36
+ 0x00, 0x46, 0x26, 0x0E, // 37
+ 0x00, 0x6C, 0x1D, 0x0B, // 38
+ 0x00, 0x89, 0x04, 0x03, // 39
+ 0x00, 0x8D, 0x0C, 0x05, // 40
+ 0x00, 0x99, 0x0B, 0x05, // 41
+ 0x00, 0xA4, 0x0D, 0x06, // 42
+ 0x00, 0xB1, 0x17, 0x09, // 43
+ 0x00, 0xC8, 0x09, 0x04, // 44
+ 0x00, 0xD1, 0x0B, 0x05, // 45
+ 0x00, 0xDC, 0x08, 0x04, // 46
+ 0x00, 0xE4, 0x0A, 0x05, // 47
+ 0x00, 0xEE, 0x17, 0x09, // 48
+ 0x01, 0x05, 0x11, 0x07, // 49
+ 0x01, 0x16, 0x17, 0x09, // 50
+ 0x01, 0x2D, 0x17, 0x09, // 51
+ 0x01, 0x44, 0x17, 0x09, // 52
+ 0x01, 0x5B, 0x17, 0x09, // 53
+ 0x01, 0x72, 0x17, 0x09, // 54
+ 0x01, 0x89, 0x16, 0x09, // 55
+ 0x01, 0x9F, 0x17, 0x09, // 56
+ 0x01, 0xB6, 0x17, 0x09, // 57
+ 0x01, 0xCD, 0x05, 0x03, // 58
+ 0x01, 0xD2, 0x06, 0x03, // 59
+ 0x01, 0xD8, 0x17, 0x09, // 60
+ 0x01, 0xEF, 0x17, 0x09, // 61
+ 0x02, 0x06, 0x17, 0x09, // 62
+ 0x02, 0x1D, 0x16, 0x09, // 63
+ 0x02, 0x33, 0x2F, 0x11, // 64
+ 0x02, 0x62, 0x1D, 0x0B, // 65
+ 0x02, 0x7F, 0x1D, 0x0B, // 66
+ 0x02, 0x9C, 0x20, 0x0C, // 67
+ 0x02, 0xBC, 0x20, 0x0C, // 68
+ 0x02, 0xDC, 0x1D, 0x0B, // 69
+ 0x02, 0xF9, 0x19, 0x0A, // 70
+ 0x03, 0x12, 0x20, 0x0C, // 71
+ 0x03, 0x32, 0x1D, 0x0B, // 72
+ 0x03, 0x4F, 0x05, 0x03, // 73
+ 0x03, 0x54, 0x14, 0x08, // 74
+ 0x03, 0x68, 0x1D, 0x0B, // 75
+ 0x03, 0x85, 0x17, 0x09, // 76
+ 0x03, 0x9C, 0x23, 0x0D, // 77
+ 0x03, 0xBF, 0x1D, 0x0B, // 78
+ 0x03, 0xDC, 0x20, 0x0C, // 79
+ 0x03, 0xFC, 0x1C, 0x0B, // 80
+ 0x04, 0x18, 0x20, 0x0C, // 81
+ 0x04, 0x38, 0x1D, 0x0B, // 82
+ 0x04, 0x55, 0x1D, 0x0B, // 83
+ 0x04, 0x72, 0x19, 0x0A, // 84
+ 0x04, 0x8B, 0x1D, 0x0B, // 85
+ 0x04, 0xA8, 0x1C, 0x0B, // 86
+ 0x04, 0xC4, 0x2B, 0x10, // 87
+ 0x04, 0xEF, 0x20, 0x0C, // 88
+ 0x05, 0x0F, 0x19, 0x0A, // 89
+ 0x05, 0x28, 0x1A, 0x0A, // 90
+ 0x05, 0x42, 0x0C, 0x05, // 91
+ 0x05, 0x4E, 0x0B, 0x05, // 92
+ 0x05, 0x59, 0x09, 0x04, // 93
+ 0x05, 0x62, 0x14, 0x08, // 94
+ 0x05, 0x76, 0x1B, 0x0A, // 95
+ 0x05, 0x91, 0x07, 0x04, // 96
+ 0x05, 0x98, 0x17, 0x09, // 97
+ 0x05, 0xAF, 0x17, 0x09, // 98
+ 0x05, 0xC6, 0x14, 0x08, // 99
+ 0x05, 0xDA, 0x17, 0x09, // 100
+ 0x05, 0xF1, 0x17, 0x09, // 101
+ 0x06, 0x08, 0x0A, 0x05, // 102
+ 0x06, 0x12, 0x17, 0x09, // 103
+ 0x06, 0x29, 0x14, 0x08, // 104
+ 0x06, 0x3D, 0x05, 0x03, // 105
+ 0x06, 0x42, 0x06, 0x03, // 106
+ 0x06, 0x48, 0x17, 0x09, // 107
+ 0x06, 0x5F, 0x05, 0x03, // 108
+ 0x06, 0x64, 0x23, 0x0D, // 109
+ 0x06, 0x87, 0x14, 0x08, // 110
+ 0x06, 0x9B, 0x17, 0x09, // 111
+ 0x06, 0xB2, 0x17, 0x09, // 112
+ 0x06, 0xC9, 0x18, 0x09, // 113
+ 0x06, 0xE1, 0x0D, 0x06, // 114
+ 0x06, 0xEE, 0x14, 0x08, // 115
+ 0x07, 0x02, 0x0B, 0x05, // 116
+ 0x07, 0x0D, 0x14, 0x08, // 117
+ 0x07, 0x21, 0x13, 0x08, // 118
+ 0x07, 0x34, 0x1F, 0x0C, // 119
+ 0x07, 0x53, 0x14, 0x08, // 120
+ 0x07, 0x67, 0x13, 0x08, // 121
+ 0x07, 0x7A, 0x14, 0x08, // 122
+ 0x07, 0x8E, 0x0F, 0x06, // 123
+ 0x07, 0x9D, 0x06, 0x03, // 124
+ 0x07, 0xA3, 0x0E, 0x06, // 125
+ 0x07, 0xB1, 0x17, 0x09, // 126
+ 0xFF, 0xFF, 0x00, 0x10, // 127
+ 0xFF, 0xFF, 0x00, 0x10, // 128
+ 0x07, 0xC8, 0x17, 0x09, // 129
+ 0x07, 0xDF, 0x07, 0x04, // 130
+ 0x07, 0xE6, 0x1D, 0x0B, // 131
+ 0x08, 0x03, 0x1E, 0x0B, // 132
+ 0x08, 0x21, 0x1B, 0x0A, // 133
+ 0x08, 0x3C, 0x20, 0x0C, // 134
+ 0x08, 0x5C, 0x14, 0x08, // 135
+ 0x08, 0x70, 0x14, 0x08, // 136
+ 0x08, 0x84, 0x14, 0x08, // 137
+ 0xFF, 0xFF, 0x00, 0x10, // 138
+ 0xFF, 0xFF, 0x00, 0x10, // 139
+ 0xFF, 0xFF, 0x00, 0x10, // 140
+ 0xFF, 0xFF, 0x00, 0x10, // 141
+ 0xFF, 0xFF, 0x00, 0x10, // 142
+ 0xFF, 0xFF, 0x00, 0x10, // 143
+ 0xFF, 0xFF, 0x00, 0x10, // 144
+ 0xFF, 0xFF, 0x00, 0x10, // 145
+ 0xFF, 0xFF, 0x00, 0x10, // 146
+ 0x08, 0x98, 0x20, 0x0C, // 147
+ 0x08, 0xB8, 0x17, 0x09, // 148
+ 0xFF, 0xFF, 0x00, 0x10, // 149
+ 0xFF, 0xFF, 0x00, 0x10, // 150
+ 0xFF, 0xFF, 0x00, 0x10, // 151
+ 0x08, 0xCF, 0x1D, 0x0B, // 152
+ 0x08, 0xEC, 0x17, 0x09, // 153
+ 0x09, 0x03, 0x1D, 0x0B, // 154
+ 0x09, 0x20, 0x14, 0x08, // 155
+ 0xFF, 0xFF, 0x00, 0x10, // 156
+ 0xFF, 0xFF, 0x00, 0x10, // 157
+ 0xFF, 0xFF, 0x00, 0x10, // 158
+ 0xFF, 0xFF, 0x00, 0x10, // 159
+ 0xFF, 0xFF, 0x00, 0x10, // 160
+ 0x09, 0x34, 0x09, 0x04, // 161
+ 0x09, 0x3D, 0x17, 0x09, // 162
+ 0x09, 0x54, 0x17, 0x09, // 163
+ 0x09, 0x6B, 0x14, 0x08, // 164
+ 0x09, 0x7F, 0x1A, 0x0A, // 165
+ 0x09, 0x99, 0x06, 0x03, // 166
+ 0x09, 0x9F, 0x17, 0x09, // 167
+ 0x09, 0xB6, 0x07, 0x04, // 168
+ 0x09, 0xBD, 0x23, 0x0D, // 169
+ 0x09, 0xE0, 0x0E, 0x06, // 170
+ 0x09, 0xEE, 0x14, 0x08, // 171
+ 0x0A, 0x02, 0x17, 0x09, // 172
+ 0x0A, 0x19, 0x0B, 0x05, // 173
+ 0x0A, 0x24, 0x23, 0x0D, // 174
+ 0x0A, 0x47, 0x19, 0x0A, // 175
+ 0x0A, 0x60, 0x0D, 0x06, // 176
+ 0x0A, 0x6D, 0x17, 0x09, // 177
+ 0x0A, 0x84, 0x0E, 0x06, // 178
+ 0x0A, 0x92, 0x0D, 0x06, // 179
+ 0x0A, 0x9F, 0x0A, 0x05, // 180
+ 0x0A, 0xA9, 0x17, 0x09, // 181
+ 0x0A, 0xC0, 0x19, 0x0A, // 182
+ 0x0A, 0xD9, 0x08, 0x04, // 183
+ 0x0A, 0xE1, 0x0C, 0x05, // 184
+ 0x0A, 0xED, 0x1A, 0x0A, // 185
+ 0x0B, 0x07, 0x0D, 0x06, // 186
+ 0x0B, 0x14, 0x1A, 0x0A, // 187
+ 0x0B, 0x2E, 0x14, 0x08, // 188
+ 0x0B, 0x42, 0x26, 0x0E, // 189
+ 0x0B, 0x68, 0x26, 0x0E, // 190
+ 0x0B, 0x8E, 0x1A, 0x0A, // 191
+ 0x0B, 0xA8, 0x1D, 0x0B, // 192
+ 0x0B, 0xC5, 0x1D, 0x0B, // 193
+ 0x0B, 0xE2, 0x1D, 0x0B, // 194
+ 0x0B, 0xFF, 0x1D, 0x0B, // 195
+ 0x0C, 0x1C, 0x1D, 0x0B, // 196
+ 0x0C, 0x39, 0x1D, 0x0B, // 197
+ 0x0C, 0x56, 0x2C, 0x10, // 198
+ 0x0C, 0x82, 0x20, 0x0C, // 199
+ 0x0C, 0xA2, 0x1D, 0x0B, // 200
+ 0x0C, 0xBF, 0x1D, 0x0B, // 201
+ 0x0C, 0xDC, 0x1D, 0x0B, // 202
+ 0x0C, 0xF9, 0x1D, 0x0B, // 203
+ 0x0D, 0x16, 0x05, 0x03, // 204
+ 0x0D, 0x1B, 0x07, 0x04, // 205
+ 0x0D, 0x22, 0x0A, 0x05, // 206
+ 0x0D, 0x2C, 0x07, 0x04, // 207
+ 0x0D, 0x33, 0x20, 0x0C, // 208
+ 0x0D, 0x53, 0x1D, 0x0B, // 209
+ 0x0D, 0x70, 0x20, 0x0C, // 210
+ 0x0D, 0x90, 0x20, 0x0C, // 211
+ 0x0D, 0xB0, 0x20, 0x0C, // 212
+ 0x0D, 0xD0, 0x20, 0x0C, // 213
+ 0x0D, 0xF0, 0x20, 0x0C, // 214
+ 0x0E, 0x10, 0x17, 0x09, // 215
+ 0x0E, 0x27, 0x20, 0x0C, // 216
+ 0x0E, 0x47, 0x1D, 0x0B, // 217
+ 0x0E, 0x64, 0x1D, 0x0B, // 218
+ 0x0E, 0x81, 0x1D, 0x0B, // 219
+ 0x0E, 0x9E, 0x1D, 0x0B, // 220
+ 0x0E, 0xBB, 0x19, 0x0A, // 221
+ 0x0E, 0xD4, 0x1D, 0x0B, // 222
+ 0x0E, 0xF1, 0x17, 0x09, // 223
+ 0x0F, 0x08, 0x17, 0x09, // 224
+ 0x0F, 0x1F, 0x17, 0x09, // 225
+ 0x0F, 0x36, 0x17, 0x09, // 226
+ 0x0F, 0x4D, 0x17, 0x09, // 227
+ 0x0F, 0x64, 0x17, 0x09, // 228
+ 0x0F, 0x7B, 0x17, 0x09, // 229
+ 0x0F, 0x92, 0x29, 0x0F, // 230
+ 0x0F, 0xBB, 0x14, 0x08, // 231
+ 0x0F, 0xCF, 0x17, 0x09, // 232
+ 0x0F, 0xE6, 0x17, 0x09, // 233
+ 0x0F, 0xFD, 0x17, 0x09, // 234
+ 0x10, 0x14, 0x17, 0x09, // 235
+ 0x10, 0x2B, 0x05, 0x03, // 236
+ 0x10, 0x30, 0x07, 0x04, // 237
+ 0x10, 0x37, 0x0A, 0x05, // 238
+ 0x10, 0x41, 0x07, 0x04, // 239
+ 0x10, 0x48, 0x17, 0x09, // 240
+ 0x10, 0x5F, 0x14, 0x08, // 241
+ 0x10, 0x73, 0x17, 0x09, // 242
+ 0x10, 0x8A, 0x17, 0x09, // 243
+ 0x10, 0xA1, 0x17, 0x09, // 244
+ 0x10, 0xB8, 0x17, 0x09, // 245
+ 0x10, 0xCF, 0x17, 0x09, // 246
+ 0x10, 0xE6, 0x17, 0x09, // 247
+ 0x10, 0xFD, 0x17, 0x09, // 248
+ 0x11, 0x14, 0x14, 0x08, // 249
+ 0x11, 0x28, 0x14, 0x08, // 250
+ 0x11, 0x3C, 0x14, 0x08, // 251
+ 0x11, 0x50, 0x14, 0x08, // 252
+ 0x11, 0x64, 0x13, 0x08, // 253
+ 0x11, 0x77, 0x17, 0x09, // 254
+ 0x11, 0x8E, 0x13, 0x08, // 255
+ // Font Data:
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0x5F, // 33
+ 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, // 34
+ 0x80, 0x08, 0x00, 0x80, 0x78, 0x00, 0xC0, 0x0F, 0x00, 0xB8, 0x08, 0x00, 0x80, 0x08, 0x00, 0x80, 0x78, 0x00, 0xC0, 0x0F, 0x00, 0xB8, 0x08, 0x00, 0x80, 0x08, // 35
+ 0x00, 0x00, 0x00, 0xE0, 0x10, 0x00, 0x10, 0x21, 0x00, 0x08, 0x41, 0x00, 0xFC, 0xFF, 0x00, 0x08, 0x42, 0x00, 0x10, 0x22, 0x00, 0x20, 0x1C, // 36
+ 0x00, 0x00, 0x00, 0xF0, 0x00, 0x00, 0x08, 0x01, 0x00, 0x08, 0x01, 0x00, 0x08, 0x61, 0x00, 0xF0, 0x18, 0x00, 0x00, 0x06, 0x00, 0xC0, 0x01, 0x00, 0x30, 0x3C, 0x00, 0x08, 0x42, 0x00, 0x00, 0x42, 0x00, 0x00, 0x42, 0x00, 0x00, 0x3C, // 37
+ 0x00, 0x00, 0x00, 0x00, 0x1C, 0x00, 0x70, 0x22, 0x00, 0x88, 0x41, 0x00, 0x08, 0x43, 0x00, 0x88, 0x44, 0x00, 0x70, 0x28, 0x00, 0x00, 0x10, 0x00, 0x00, 0x28, 0x00, 0x00, 0x44, // 38
+ 0x00, 0x00, 0x00, 0x78, // 39
+ 0x00, 0x00, 0x00, 0x80, 0x3F, 0x00, 0x70, 0xC0, 0x01, 0x08, 0x00, 0x02, // 40
+ 0x00, 0x00, 0x00, 0x08, 0x00, 0x02, 0x70, 0xC0, 0x01, 0x80, 0x3F, // 41
+ 0x10, 0x00, 0x00, 0xD0, 0x00, 0x00, 0x38, 0x00, 0x00, 0xD0, 0x00, 0x00, 0x10, // 42
+ 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x02, 0x00, 0x00, 0x02, 0x00, 0xC0, 0x1F, 0x00, 0x00, 0x02, 0x00, 0x00, 0x02, 0x00, 0x00, 0x02, // 43
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x01, // 44
+ 0x00, 0x08, 0x00, 0x00, 0x08, 0x00, 0x00, 0x08, 0x00, 0x00, 0x08, // 45
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, // 46
+ 0x00, 0x60, 0x00, 0x00, 0x1E, 0x00, 0xE0, 0x01, 0x00, 0x18, // 47
+ 0x00, 0x00, 0x00, 0xE0, 0x1F, 0x00, 0x10, 0x20, 0x00, 0x08, 0x40, 0x00, 0x08, 0x40, 0x00, 0x08, 0x40, 0x00, 0x10, 0x20, 0x00, 0xE0, 0x1F, // 48
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x20, 0x00, 0x00, 0x10, 0x00, 0x00, 0xF8, 0x7F, // 49
+ 0x00, 0x00, 0x00, 0x20, 0x40, 0x00, 0x10, 0x60, 0x00, 0x08, 0x50, 0x00, 0x08, 0x48, 0x00, 0x08, 0x44, 0x00, 0x10, 0x43, 0x00, 0xE0, 0x40, // 50
+ 0x00, 0x00, 0x00, 0x20, 0x10, 0x00, 0x10, 0x20, 0x00, 0x08, 0x41, 0x00, 0x08, 0x41, 0x00, 0x88, 0x41, 0x00, 0xF0, 0x22, 0x00, 0x00, 0x1C, // 51
+ 0x00, 0x0C, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x09, 0x00, 0xC0, 0x08, 0x00, 0x20, 0x08, 0x00, 0x10, 0x08, 0x00, 0xF8, 0x7F, 0x00, 0x00, 0x08, // 52
+ 0x00, 0x00, 0x00, 0xC0, 0x11, 0x00, 0xB8, 0x20, 0x00, 0x88, 0x40, 0x00, 0x88, 0x40, 0x00, 0x88, 0x40, 0x00, 0x08, 0x21, 0x00, 0x08, 0x1E, // 53
+ 0x00, 0x00, 0x00, 0xE0, 0x1F, 0x00, 0x10, 0x21, 0x00, 0x88, 0x40, 0x00, 0x88, 0x40, 0x00, 0x88, 0x40, 0x00, 0x10, 0x21, 0x00, 0x20, 0x1E, // 54
+ 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x08, 0x00, 0x00, 0x08, 0x78, 0x00, 0x08, 0x07, 0x00, 0xC8, 0x00, 0x00, 0x28, 0x00, 0x00, 0x18, // 55
+ 0x00, 0x00, 0x00, 0x60, 0x1C, 0x00, 0x90, 0x22, 0x00, 0x08, 0x41, 0x00, 0x08, 0x41, 0x00, 0x08, 0x41, 0x00, 0x90, 0x22, 0x00, 0x60, 0x1C, // 56
+ 0x00, 0x00, 0x00, 0xE0, 0x11, 0x00, 0x10, 0x22, 0x00, 0x08, 0x44, 0x00, 0x08, 0x44, 0x00, 0x08, 0x44, 0x00, 0x10, 0x22, 0x00, 0xE0, 0x1F, // 57
+ 0x00, 0x00, 0x00, 0x40, 0x40, // 58
+ 0x00, 0x00, 0x00, 0x40, 0xC0, 0x01, // 59
+ 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x05, 0x00, 0x00, 0x05, 0x00, 0x80, 0x08, 0x00, 0x80, 0x08, 0x00, 0x80, 0x08, 0x00, 0x40, 0x10, // 60
+ 0x00, 0x00, 0x00, 0x80, 0x08, 0x00, 0x80, 0x08, 0x00, 0x80, 0x08, 0x00, 0x80, 0x08, 0x00, 0x80, 0x08, 0x00, 0x80, 0x08, 0x00, 0x80, 0x08, // 61
+ 0x00, 0x00, 0x00, 0x40, 0x10, 0x00, 0x80, 0x08, 0x00, 0x80, 0x08, 0x00, 0x80, 0x08, 0x00, 0x00, 0x05, 0x00, 0x00, 0x05, 0x00, 0x00, 0x02, // 62
+ 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x10, 0x00, 0x00, 0x08, 0x00, 0x00, 0x08, 0x5C, 0x00, 0x08, 0x02, 0x00, 0x10, 0x01, 0x00, 0xE0, // 63
+ 0x00, 0x00, 0x00, 0x00, 0x3F, 0x00, 0xC0, 0x40, 0x00, 0x20, 0x80, 0x00, 0x10, 0x1E, 0x01, 0x10, 0x21, 0x01, 0x88, 0x40, 0x02, 0x48, 0x40, 0x02, 0x48, 0x40, 0x02, 0x48, 0x20, 0x02, 0x88, 0x7C, 0x02, 0xC8, 0x43, 0x02, 0x10, 0x40, 0x02, 0x10, 0x20, 0x01, 0x60, 0x10, 0x01, 0x80, 0x8F, // 64
+ 0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x1C, 0x00, 0x80, 0x07, 0x00, 0x70, 0x04, 0x00, 0x08, 0x04, 0x00, 0x70, 0x04, 0x00, 0x80, 0x07, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x60, // 65
+ 0x00, 0x00, 0x00, 0xF8, 0x7F, 0x00, 0x08, 0x41, 0x00, 0x08, 0x41, 0x00, 0x08, 0x41, 0x00, 0x08, 0x41, 0x00, 0x08, 0x41, 0x00, 0x08, 0x41, 0x00, 0x90, 0x22, 0x00, 0x60, 0x1C, // 66
+ 0x00, 0x00, 0x00, 0xC0, 0x0F, 0x00, 0x20, 0x10, 0x00, 0x10, 0x20, 0x00, 0x08, 0x40, 0x00, 0x08, 0x40, 0x00, 0x08, 0x40, 0x00, 0x08, 0x40, 0x00, 0x08, 0x40, 0x00, 0x10, 0x20, 0x00, 0x20, 0x10, // 67
+ 0x00, 0x00, 0x00, 0xF8, 0x7F, 0x00, 0x08, 0x40, 0x00, 0x08, 0x40, 0x00, 0x08, 0x40, 0x00, 0x08, 0x40, 0x00, 0x08, 0x40, 0x00, 0x08, 0x40, 0x00, 0x10, 0x20, 0x00, 0x20, 0x10, 0x00, 0xC0, 0x0F, // 68
+ 0x00, 0x00, 0x00, 0xF8, 0x7F, 0x00, 0x08, 0x41, 0x00, 0x08, 0x41, 0x00, 0x08, 0x41, 0x00, 0x08, 0x41, 0x00, 0x08, 0x41, 0x00, 0x08, 0x41, 0x00, 0x08, 0x41, 0x00, 0x08, 0x40, // 69
+ 0x00, 0x00, 0x00, 0xF8, 0x7F, 0x00, 0x08, 0x02, 0x00, 0x08, 0x02, 0x00, 0x08, 0x02, 0x00, 0x08, 0x02, 0x00, 0x08, 0x02, 0x00, 0x08, 0x02, 0x00, 0x08, // 70
+ 0x00, 0x00, 0x00, 0xC0, 0x0F, 0x00, 0x20, 0x10, 0x00, 0x10, 0x20, 0x00, 0x08, 0x40, 0x00, 0x08, 0x40, 0x00, 0x08, 0x42, 0x00, 0x08, 0x42, 0x00, 0x10, 0x22, 0x00, 0x20, 0x12, 0x00, 0x00, 0x0E, // 71
+ 0x00, 0x00, 0x00, 0xF8, 0x7F, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0xF8, 0x7F, // 72
+ 0x00, 0x00, 0x00, 0xF8, 0x7F, // 73
+ 0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x40, 0x00, 0x00, 0x40, 0x00, 0x00, 0x40, 0x00, 0x00, 0x40, 0x00, 0xF8, 0x3F, // 74
+ 0x00, 0x00, 0x00, 0xF8, 0x7F, 0x00, 0x00, 0x04, 0x00, 0x00, 0x02, 0x00, 0x00, 0x01, 0x00, 0x80, 0x03, 0x00, 0x40, 0x04, 0x00, 0x20, 0x18, 0x00, 0x10, 0x20, 0x00, 0x08, 0x40, // 75
+ 0x00, 0x00, 0x00, 0xF8, 0x7F, 0x00, 0x00, 0x40, 0x00, 0x00, 0x40, 0x00, 0x00, 0x40, 0x00, 0x00, 0x40, 0x00, 0x00, 0x40, 0x00, 0x00, 0x40, // 76
+ 0x00, 0x00, 0x00, 0xF8, 0x7F, 0x00, 0x30, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x60, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x03, 0x00, 0xC0, 0x00, 0x00, 0x30, 0x00, 0x00, 0xF8, 0x7F, // 77
+ 0x00, 0x00, 0x00, 0xF8, 0x7F, 0x00, 0x10, 0x00, 0x00, 0x60, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x04, 0x00, 0x00, 0x18, 0x00, 0x00, 0x20, 0x00, 0xF8, 0x7F, // 78
+ 0x00, 0x00, 0x00, 0xC0, 0x0F, 0x00, 0x20, 0x10, 0x00, 0x10, 0x20, 0x00, 0x08, 0x40, 0x00, 0x08, 0x40, 0x00, 0x08, 0x40, 0x00, 0x08, 0x40, 0x00, 0x10, 0x20, 0x00, 0x20, 0x10, 0x00, 0xC0, 0x0F, // 79
+ 0x00, 0x00, 0x00, 0xF8, 0x7F, 0x00, 0x08, 0x02, 0x00, 0x08, 0x02, 0x00, 0x08, 0x02, 0x00, 0x08, 0x02, 0x00, 0x08, 0x02, 0x00, 0x08, 0x02, 0x00, 0x10, 0x01, 0x00, 0xE0, // 80
+ 0x00, 0x00, 0x00, 0xC0, 0x0F, 0x00, 0x20, 0x10, 0x00, 0x10, 0x20, 0x00, 0x08, 0x40, 0x00, 0x08, 0x40, 0x00, 0x08, 0x50, 0x00, 0x08, 0x50, 0x00, 0x10, 0x20, 0x00, 0x20, 0x70, 0x00, 0xC0, 0x4F, // 81
+ 0x00, 0x00, 0x00, 0xF8, 0x7F, 0x00, 0x08, 0x02, 0x00, 0x08, 0x02, 0x00, 0x08, 0x02, 0x00, 0x08, 0x02, 0x00, 0x08, 0x06, 0x00, 0x08, 0x1A, 0x00, 0x10, 0x21, 0x00, 0xE0, 0x40, // 82
+ 0x00, 0x00, 0x00, 0x60, 0x10, 0x00, 0x90, 0x20, 0x00, 0x08, 0x41, 0x00, 0x08, 0x41, 0x00, 0x08, 0x41, 0x00, 0x08, 0x42, 0x00, 0x08, 0x42, 0x00, 0x10, 0x22, 0x00, 0x20, 0x1C, // 83
+ 0x08, 0x00, 0x00, 0x08, 0x00, 0x00, 0x08, 0x00, 0x00, 0x08, 0x00, 0x00, 0xF8, 0x7F, 0x00, 0x08, 0x00, 0x00, 0x08, 0x00, 0x00, 0x08, 0x00, 0x00, 0x08, // 84
+ 0x00, 0x00, 0x00, 0xF8, 0x1F, 0x00, 0x00, 0x20, 0x00, 0x00, 0x40, 0x00, 0x00, 0x40, 0x00, 0x00, 0x40, 0x00, 0x00, 0x40, 0x00, 0x00, 0x40, 0x00, 0x00, 0x20, 0x00, 0xF8, 0x1F, // 85
+ 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0xE0, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x18, 0x00, 0x00, 0x60, 0x00, 0x00, 0x18, 0x00, 0x00, 0x07, 0x00, 0xE0, 0x00, 0x00, 0x18, // 86
+ 0x18, 0x00, 0x00, 0xE0, 0x01, 0x00, 0x00, 0x1E, 0x00, 0x00, 0x60, 0x00, 0x00, 0x1C, 0x00, 0x80, 0x03, 0x00, 0x70, 0x00, 0x00, 0x08, 0x00, 0x00, 0x70, 0x00, 0x00, 0x80, 0x03, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x60, 0x00, 0x00, 0x1E, 0x00, 0xE0, 0x01, 0x00, 0x18, // 87
+ 0x00, 0x40, 0x00, 0x08, 0x20, 0x00, 0x10, 0x10, 0x00, 0x60, 0x0C, 0x00, 0x80, 0x02, 0x00, 0x00, 0x01, 0x00, 0x80, 0x02, 0x00, 0x60, 0x0C, 0x00, 0x10, 0x10, 0x00, 0x08, 0x20, 0x00, 0x00, 0x40, // 88
+ 0x08, 0x00, 0x00, 0x30, 0x00, 0x00, 0x40, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x7E, 0x00, 0x80, 0x01, 0x00, 0x40, 0x00, 0x00, 0x30, 0x00, 0x00, 0x08, // 89
+ 0x00, 0x40, 0x00, 0x08, 0x60, 0x00, 0x08, 0x58, 0x00, 0x08, 0x44, 0x00, 0x08, 0x43, 0x00, 0x88, 0x40, 0x00, 0x68, 0x40, 0x00, 0x18, 0x40, 0x00, 0x08, 0x40, // 90
+ 0x00, 0x00, 0x00, 0xF8, 0xFF, 0x03, 0x08, 0x00, 0x02, 0x08, 0x00, 0x02, // 91
+ 0x18, 0x00, 0x00, 0xE0, 0x01, 0x00, 0x00, 0x1E, 0x00, 0x00, 0x60, // 92
+ 0x08, 0x00, 0x02, 0x08, 0x00, 0x02, 0xF8, 0xFF, 0x03, // 93
+ 0x00, 0x01, 0x00, 0xC0, 0x00, 0x00, 0x30, 0x00, 0x00, 0x08, 0x00, 0x00, 0x30, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0x01, // 94
+ 0x00, 0x00, 0x02, 0x00, 0x00, 0x02, 0x00, 0x00, 0x02, 0x00, 0x00, 0x02, 0x00, 0x00, 0x02, 0x00, 0x00, 0x02, 0x00, 0x00, 0x02, 0x00, 0x00, 0x02, 0x00, 0x00, 0x02, // 95
+ 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x10, // 96
+ 0x00, 0x00, 0x00, 0x00, 0x39, 0x00, 0x80, 0x44, 0x00, 0x40, 0x44, 0x00, 0x40, 0x44, 0x00, 0x40, 0x42, 0x00, 0x40, 0x22, 0x00, 0x80, 0x7F, // 97
+ 0x00, 0x00, 0x00, 0xF8, 0x7F, 0x00, 0x80, 0x20, 0x00, 0x40, 0x40, 0x00, 0x40, 0x40, 0x00, 0x40, 0x40, 0x00, 0x80, 0x20, 0x00, 0x00, 0x1F, // 98
+ 0x00, 0x00, 0x00, 0x00, 0x1F, 0x00, 0x80, 0x20, 0x00, 0x40, 0x40, 0x00, 0x40, 0x40, 0x00, 0x40, 0x40, 0x00, 0x80, 0x20, // 99
+ 0x00, 0x00, 0x00, 0x00, 0x1F, 0x00, 0x80, 0x20, 0x00, 0x40, 0x40, 0x00, 0x40, 0x40, 0x00, 0x40, 0x40, 0x00, 0x80, 0x20, 0x00, 0xF8, 0x7F, // 100
+ 0x00, 0x00, 0x00, 0x00, 0x1F, 0x00, 0x80, 0x24, 0x00, 0x40, 0x44, 0x00, 0x40, 0x44, 0x00, 0x40, 0x44, 0x00, 0x80, 0x24, 0x00, 0x00, 0x17, // 101
+ 0x40, 0x00, 0x00, 0xF0, 0x7F, 0x00, 0x48, 0x00, 0x00, 0x48, // 102
+ 0x00, 0x00, 0x00, 0x00, 0x1F, 0x01, 0x80, 0x20, 0x02, 0x40, 0x40, 0x02, 0x40, 0x40, 0x02, 0x40, 0x40, 0x02, 0x80, 0x20, 0x01, 0xC0, 0xFF, // 103
+ 0x00, 0x00, 0x00, 0xF8, 0x7F, 0x00, 0x80, 0x00, 0x00, 0x40, 0x00, 0x00, 0x40, 0x00, 0x00, 0x40, 0x00, 0x00, 0x80, 0x7F, // 104
+ 0x00, 0x00, 0x00, 0xC8, 0x7F, // 105
+ 0x00, 0x00, 0x02, 0xC8, 0xFF, 0x01, // 106
+ 0x00, 0x00, 0x00, 0xF8, 0x7F, 0x00, 0x00, 0x08, 0x00, 0x00, 0x04, 0x00, 0x00, 0x06, 0x00, 0x00, 0x19, 0x00, 0x80, 0x20, 0x00, 0x40, 0x40, // 107
+ 0x00, 0x00, 0x00, 0xF8, 0x7F, // 108
+ 0x00, 0x00, 0x00, 0xC0, 0x7F, 0x00, 0x80, 0x00, 0x00, 0x40, 0x00, 0x00, 0x40, 0x00, 0x00, 0x40, 0x00, 0x00, 0x80, 0x7F, 0x00, 0x80, 0x00, 0x00, 0x40, 0x00, 0x00, 0x40, 0x00, 0x00, 0x40, 0x00, 0x00, 0x80, 0x7F, // 109
+ 0x00, 0x00, 0x00, 0xC0, 0x7F, 0x00, 0x80, 0x00, 0x00, 0x40, 0x00, 0x00, 0x40, 0x00, 0x00, 0x40, 0x00, 0x00, 0x80, 0x7F, // 110
+ 0x00, 0x00, 0x00, 0x00, 0x1F, 0x00, 0x80, 0x20, 0x00, 0x40, 0x40, 0x00, 0x40, 0x40, 0x00, 0x40, 0x40, 0x00, 0x80, 0x20, 0x00, 0x00, 0x1F, // 111
+ 0x00, 0x00, 0x00, 0xC0, 0xFF, 0x03, 0x80, 0x20, 0x00, 0x40, 0x40, 0x00, 0x40, 0x40, 0x00, 0x40, 0x40, 0x00, 0x80, 0x20, 0x00, 0x00, 0x1F, // 112
+ 0x00, 0x00, 0x00, 0x00, 0x1F, 0x00, 0x80, 0x20, 0x00, 0x40, 0x40, 0x00, 0x40, 0x40, 0x00, 0x40, 0x40, 0x00, 0x80, 0x20, 0x00, 0xC0, 0xFF, 0x03, // 113
+ 0x00, 0x00, 0x00, 0xC0, 0x7F, 0x00, 0x80, 0x00, 0x00, 0x40, 0x00, 0x00, 0x40, // 114
+ 0x00, 0x00, 0x00, 0x80, 0x23, 0x00, 0x40, 0x44, 0x00, 0x40, 0x44, 0x00, 0x40, 0x44, 0x00, 0x40, 0x44, 0x00, 0x80, 0x38, // 115
+ 0x40, 0x00, 0x00, 0xF0, 0x7F, 0x00, 0x40, 0x40, 0x00, 0x40, 0x40, // 116
+ 0x00, 0x00, 0x00, 0xC0, 0x3F, 0x00, 0x00, 0x40, 0x00, 0x00, 0x40, 0x00, 0x00, 0x40, 0x00, 0x00, 0x20, 0x00, 0xC0, 0x7F, // 117
+ 0xC0, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x60, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x03, 0x00, 0xC0, // 118
+ 0xC0, 0x00, 0x00, 0x00, 0x1F, 0x00, 0x00, 0x60, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x03, 0x00, 0xC0, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x60, 0x00, 0x00, 0x1F, 0x00, 0xC0, // 119
+ 0x40, 0x40, 0x00, 0x80, 0x20, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x04, 0x00, 0x00, 0x1B, 0x00, 0x80, 0x20, 0x00, 0x40, 0x40, // 120
+ 0xC0, 0x01, 0x00, 0x00, 0x06, 0x02, 0x00, 0x38, 0x02, 0x00, 0xE0, 0x01, 0x00, 0x38, 0x00, 0x00, 0x07, 0x00, 0xC0, // 121
+ 0x40, 0x40, 0x00, 0x40, 0x60, 0x00, 0x40, 0x58, 0x00, 0x40, 0x44, 0x00, 0x40, 0x43, 0x00, 0xC0, 0x40, 0x00, 0x40, 0x40, // 122
+ 0x00, 0x04, 0x00, 0x00, 0x04, 0x00, 0xF0, 0xFB, 0x01, 0x08, 0x00, 0x02, 0x08, 0x00, 0x02, // 123
+ 0x00, 0x00, 0x00, 0xF8, 0xFF, 0x03, // 124
+ 0x08, 0x00, 0x02, 0x08, 0x00, 0x02, 0xF0, 0xFB, 0x01, 0x00, 0x04, 0x00, 0x00, 0x04, // 125
+ 0x00, 0x02, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x02, 0x00, 0x00, 0x02, 0x00, 0x00, 0x02, 0x00, 0x00, 0x01, // 126
+ 0x00, 0x00, 0x00, 0xF8, 0x7F, 0x00, 0x00, 0x42, 0x00, 0x00, 0x41, 0x00, 0x80, 0x40, 0x00, 0x00, 0x40, 0x00, 0x00, 0x40, 0x00, 0x00, 0x40, // 129
+ 0x00, 0x01, 0x00, 0xF8, 0x7F, 0x00, 0x80, // 130
+ 0x00, 0x00, 0x00, 0xF8, 0x7F, 0x00, 0x10, 0x00, 0x00, 0x60, 0x00, 0x00, 0x80, 0x00, 0x00, 0x08, 0x03, 0x00, 0x04, 0x04, 0x00, 0x02, 0x18, 0x00, 0x00, 0x20, 0x00, 0xF8, 0x7F, // 131
+ 0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x1C, 0x00, 0x80, 0x07, 0x00, 0x70, 0x04, 0x00, 0x08, 0x04, 0x00, 0x70, 0x04, 0x00, 0x80, 0x07, 0x00, 0x00, 0x9C, 0x01, 0x00, 0x60, 0x02, // 132
+ 0x00, 0x00, 0x00, 0x00, 0x39, 0x00, 0x80, 0x44, 0x00, 0x40, 0x44, 0x00, 0x40, 0x44, 0x00, 0x40, 0x42, 0x00, 0x40, 0x22, 0x00, 0x80, 0x7F, 0x03, 0x00, 0x80, 0x04, // 133
+ 0x00, 0x00, 0x00, 0xC0, 0x0F, 0x00, 0x20, 0x10, 0x00, 0x10, 0x20, 0x00, 0x08, 0x40, 0x00, 0x08, 0x40, 0x00, 0x08, 0x40, 0x00, 0x0A, 0x40, 0x00, 0x09, 0x40, 0x00, 0x10, 0x20, 0x00, 0x20, 0x10, // 134
+ 0x00, 0x00, 0x00, 0x00, 0x1F, 0x00, 0x80, 0x20, 0x00, 0x40, 0x40, 0x00, 0x50, 0x40, 0x00, 0x48, 0x40, 0x00, 0x80, 0x20, // 135
+ 0x00, 0x00, 0x00, 0xC0, 0x7F, 0x00, 0x80, 0x00, 0x00, 0x40, 0x00, 0x00, 0x50, 0x00, 0x00, 0x48, 0x00, 0x00, 0x80, 0x7F, // 136
+ 0x40, 0x40, 0x00, 0x40, 0x60, 0x00, 0x40, 0x58, 0x00, 0x50, 0x44, 0x00, 0x48, 0x43, 0x00, 0xC0, 0x40, 0x00, 0x40, 0x40, // 137
+ 0x00, 0x00, 0x00, 0xC0, 0x0F, 0x00, 0x20, 0x10, 0x00, 0x10, 0x20, 0x00, 0x08, 0x40, 0x00, 0x08, 0x40, 0x00, 0x0A, 0x40, 0x00, 0x09, 0x40, 0x00, 0x10, 0x20, 0x00, 0x20, 0x10, 0x00, 0xC0, 0x0F, // 147
+ 0x00, 0x00, 0x00, 0x00, 0x1F, 0x00, 0x80, 0x20, 0x00, 0x40, 0x40, 0x00, 0x50, 0x40, 0x00, 0x48, 0x40, 0x00, 0x80, 0x20, 0x00, 0x00, 0x1F, // 148
+ 0x00, 0x00, 0x00, 0xF8, 0x7F, 0x00, 0x08, 0x41, 0x00, 0x08, 0x41, 0x00, 0x08, 0x41, 0x00, 0x08, 0x41, 0x00, 0x08, 0xC1, 0x01, 0x08, 0x41, 0x02, 0x08, 0x41, 0x00, 0x08, 0x40, // 152
+ 0x00, 0x00, 0x00, 0x00, 0x1F, 0x00, 0x80, 0x24, 0x00, 0x40, 0x44, 0x00, 0x40, 0x44, 0x03, 0x40, 0xC4, 0x04, 0x80, 0x24, 0x00, 0x00, 0x17, // 153
+ 0x00, 0x00, 0x00, 0x60, 0x10, 0x00, 0x90, 0x20, 0x00, 0x08, 0x41, 0x00, 0x08, 0x41, 0x00, 0x0A, 0x41, 0x00, 0x09, 0x42, 0x00, 0x08, 0x42, 0x00, 0x10, 0x22, 0x00, 0x20, 0x1C, // 154
+ 0x00, 0x00, 0x00, 0x80, 0x23, 0x00, 0x40, 0x44, 0x00, 0x40, 0x44, 0x00, 0x50, 0x44, 0x00, 0x48, 0x44, 0x00, 0x80, 0x38, // 155
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0xFF, 0x03, // 161
+ 0x00, 0x00, 0x00, 0x00, 0x1F, 0x00, 0x80, 0x20, 0x03, 0x40, 0xF0, 0x00, 0x40, 0x4E, 0x00, 0xC0, 0x41, 0x00, 0xB8, 0x20, 0x00, 0x00, 0x11, // 162
+ 0x00, 0x41, 0x00, 0xE0, 0x31, 0x00, 0x10, 0x2F, 0x00, 0x08, 0x21, 0x00, 0x08, 0x21, 0x00, 0x08, 0x40, 0x00, 0x10, 0x40, 0x00, 0x20, 0x20, // 163
+ 0x00, 0x00, 0x00, 0x40, 0x0B, 0x00, 0x80, 0x04, 0x00, 0x40, 0x08, 0x00, 0x40, 0x08, 0x00, 0x80, 0x04, 0x00, 0x40, 0x0B, // 164
+ 0x08, 0x0A, 0x00, 0x10, 0x0A, 0x00, 0x60, 0x0A, 0x00, 0x80, 0x0B, 0x00, 0x00, 0x7E, 0x00, 0x80, 0x0B, 0x00, 0x60, 0x0A, 0x00, 0x10, 0x0A, 0x00, 0x08, 0x0A, // 165
+ 0x00, 0x00, 0x00, 0xF8, 0xF1, 0x03, // 166
+ 0x00, 0x86, 0x00, 0x70, 0x09, 0x01, 0xC8, 0x10, 0x02, 0x88, 0x10, 0x02, 0x08, 0x21, 0x02, 0x08, 0x61, 0x02, 0x30, 0xD2, 0x01, 0x00, 0x0C, // 167
+ 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, // 168
+ 0xC0, 0x0F, 0x00, 0x20, 0x10, 0x00, 0x10, 0x20, 0x00, 0xC8, 0x47, 0x00, 0x28, 0x48, 0x00, 0x28, 0x48, 0x00, 0x28, 0x48, 0x00, 0x28, 0x48, 0x00, 0x48, 0x44, 0x00, 0x10, 0x20, 0x00, 0x20, 0x10, 0x00, 0xC0, 0x0F, // 169
+ 0xD0, 0x00, 0x00, 0x48, 0x01, 0x00, 0x28, 0x01, 0x00, 0x28, 0x01, 0x00, 0xF0, 0x01, // 170
+ 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x1B, 0x00, 0x80, 0x20, 0x00, 0x00, 0x04, 0x00, 0x00, 0x1B, 0x00, 0x80, 0x20, // 171
+ 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x80, 0x00, 0x00, 0x80, 0x00, 0x00, 0x80, 0x00, 0x00, 0x80, 0x00, 0x00, 0x80, 0x00, 0x00, 0x80, 0x0F, // 172
+ 0x00, 0x08, 0x00, 0x00, 0x08, 0x00, 0x00, 0x08, 0x00, 0x00, 0x08, // 173
+ 0xC0, 0x0F, 0x00, 0x20, 0x10, 0x00, 0x10, 0x20, 0x00, 0xE8, 0x4F, 0x00, 0x28, 0x41, 0x00, 0x28, 0x41, 0x00, 0x28, 0x43, 0x00, 0x28, 0x45, 0x00, 0xC8, 0x48, 0x00, 0x10, 0x20, 0x00, 0x20, 0x10, 0x00, 0xC0, 0x0F, // 174
+ 0x04, 0x00, 0x00, 0x04, 0x00, 0x00, 0x04, 0x00, 0x00, 0x04, 0x00, 0x00, 0x04, 0x00, 0x00, 0x04, 0x00, 0x00, 0x04, 0x00, 0x00, 0x04, 0x00, 0x00, 0x04, // 175
+ 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x48, 0x00, 0x00, 0x48, 0x00, 0x00, 0x30, // 176
+ 0x00, 0x00, 0x00, 0x00, 0x41, 0x00, 0x00, 0x41, 0x00, 0x00, 0x41, 0x00, 0xE0, 0x4F, 0x00, 0x00, 0x41, 0x00, 0x00, 0x41, 0x00, 0x00, 0x41, // 177
+ 0x10, 0x01, 0x00, 0x88, 0x01, 0x00, 0x48, 0x01, 0x00, 0x48, 0x01, 0x00, 0x30, 0x01, // 178
+ 0x90, 0x00, 0x00, 0x08, 0x01, 0x00, 0x08, 0x01, 0x00, 0x28, 0x01, 0x00, 0xD8, // 179
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x08, // 180
+ 0x00, 0x00, 0x00, 0xC0, 0xFF, 0x03, 0x00, 0x20, 0x00, 0x00, 0x40, 0x00, 0x00, 0x40, 0x00, 0x00, 0x40, 0x00, 0x00, 0x20, 0x00, 0xC0, 0x7F, // 181
+ 0xF0, 0x00, 0x00, 0xF8, 0x00, 0x00, 0xF8, 0x01, 0x00, 0xF8, 0x01, 0x00, 0xF8, 0xFF, 0x03, 0x08, 0x00, 0x00, 0x08, 0x00, 0x00, 0xF8, 0xFF, 0x03, 0x08, // 182
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, // 183
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x80, 0x02, 0x00, 0x00, 0x03, // 184
+ 0x00, 0x40, 0x00, 0x08, 0x60, 0x00, 0x08, 0x58, 0x00, 0x08, 0x44, 0x00, 0x0A, 0x43, 0x00, 0x89, 0x40, 0x00, 0x68, 0x40, 0x00, 0x18, 0x40, 0x00, 0x08, 0x40, // 185
+ 0xF0, 0x00, 0x00, 0x08, 0x01, 0x00, 0x08, 0x01, 0x00, 0x08, 0x01, 0x00, 0xF0, // 186
+ 0x00, 0x40, 0x00, 0x08, 0x60, 0x00, 0x08, 0x58, 0x00, 0x08, 0x44, 0x00, 0x0A, 0x43, 0x00, 0x88, 0x40, 0x00, 0x68, 0x40, 0x00, 0x18, 0x40, 0x00, 0x08, 0x40, // 187
+ 0x40, 0x40, 0x00, 0x40, 0x60, 0x00, 0x40, 0x58, 0x00, 0x50, 0x44, 0x00, 0x40, 0x43, 0x00, 0xC0, 0x40, 0x00, 0x40, 0x40, // 188
+ 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x08, 0x40, 0x00, 0xF8, 0x31, 0x00, 0x00, 0x08, 0x00, 0x00, 0x04, 0x00, 0x00, 0x03, 0x00, 0x80, 0x00, 0x00, 0x60, 0x44, 0x00, 0x10, 0x62, 0x00, 0x08, 0x52, 0x00, 0x00, 0x52, 0x00, 0x00, 0x4C, // 189
+ 0x90, 0x00, 0x00, 0x08, 0x01, 0x00, 0x08, 0x41, 0x00, 0x28, 0x21, 0x00, 0xD8, 0x18, 0x00, 0x00, 0x04, 0x00, 0x00, 0x03, 0x00, 0x80, 0x00, 0x00, 0x40, 0x30, 0x00, 0x30, 0x28, 0x00, 0x08, 0x24, 0x00, 0x00, 0x7E, 0x00, 0x00, 0x20, // 190
+ 0x00, 0x00, 0x00, 0x00, 0xE0, 0x00, 0x00, 0x10, 0x01, 0x00, 0x08, 0x02, 0x40, 0x07, 0x02, 0x00, 0x00, 0x02, 0x00, 0x00, 0x02, 0x00, 0x00, 0x01, 0x00, 0xC0, // 191
+ 0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x1C, 0x00, 0x80, 0x07, 0x00, 0x71, 0x04, 0x00, 0x0A, 0x04, 0x00, 0x70, 0x04, 0x00, 0x80, 0x07, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x60, // 192
+ 0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x1C, 0x00, 0x80, 0x07, 0x00, 0x70, 0x04, 0x00, 0x0A, 0x04, 0x00, 0x71, 0x04, 0x00, 0x80, 0x07, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x60, // 193
+ 0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x1C, 0x00, 0x80, 0x07, 0x00, 0x72, 0x04, 0x00, 0x09, 0x04, 0x00, 0x71, 0x04, 0x00, 0x82, 0x07, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x60, // 194
+ 0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x1C, 0x00, 0x80, 0x07, 0x00, 0x72, 0x04, 0x00, 0x09, 0x04, 0x00, 0x72, 0x04, 0x00, 0x81, 0x07, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x60, // 195
+ 0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x1C, 0x00, 0x80, 0x07, 0x00, 0x72, 0x04, 0x00, 0x08, 0x04, 0x00, 0x72, 0x04, 0x00, 0x80, 0x07, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x60, // 196
+ 0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x1C, 0x00, 0x80, 0x07, 0x00, 0x7E, 0x04, 0x00, 0x0A, 0x04, 0x00, 0x7E, 0x04, 0x00, 0x80, 0x07, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x60, // 197
+ 0x00, 0x60, 0x00, 0x00, 0x18, 0x00, 0x00, 0x06, 0x00, 0x80, 0x05, 0x00, 0x60, 0x04, 0x00, 0x18, 0x04, 0x00, 0x08, 0x04, 0x00, 0x08, 0x04, 0x00, 0xF8, 0x7F, 0x00, 0x08, 0x41, 0x00, 0x08, 0x41, 0x00, 0x08, 0x41, 0x00, 0x08, 0x41, 0x00, 0x08, 0x41, 0x00, 0x08, 0x41, // 198
+ 0x00, 0x00, 0x00, 0xC0, 0x0F, 0x00, 0x20, 0x10, 0x00, 0x10, 0x20, 0x00, 0x08, 0x40, 0x00, 0x08, 0x40, 0x02, 0x08, 0xC0, 0x02, 0x08, 0x40, 0x03, 0x08, 0x40, 0x00, 0x10, 0x20, 0x00, 0x20, 0x10, // 199
+ 0x00, 0x00, 0x00, 0xF8, 0x7F, 0x00, 0x08, 0x41, 0x00, 0x08, 0x41, 0x00, 0x08, 0x41, 0x00, 0x09, 0x41, 0x00, 0x0A, 0x41, 0x00, 0x08, 0x41, 0x00, 0x08, 0x41, 0x00, 0x08, 0x40, // 200
+ 0x00, 0x00, 0x00, 0xF8, 0x7F, 0x00, 0x08, 0x41, 0x00, 0x08, 0x41, 0x00, 0x08, 0x41, 0x00, 0x0A, 0x41, 0x00, 0x09, 0x41, 0x00, 0x08, 0x41, 0x00, 0x08, 0x41, 0x00, 0x08, 0x40, // 201
+ 0x00, 0x00, 0x00, 0xF8, 0x7F, 0x00, 0x08, 0x41, 0x00, 0x08, 0x41, 0x00, 0x0A, 0x41, 0x00, 0x09, 0x41, 0x00, 0x09, 0x41, 0x00, 0x0A, 0x41, 0x00, 0x08, 0x41, 0x00, 0x08, 0x40, // 202
+ 0x00, 0x00, 0x00, 0xF8, 0x7F, 0x00, 0x08, 0x41, 0x00, 0x08, 0x41, 0x00, 0x0A, 0x41, 0x00, 0x08, 0x41, 0x00, 0x0A, 0x41, 0x00, 0x08, 0x41, 0x00, 0x08, 0x41, 0x00, 0x08, 0x40, // 203
+ 0x01, 0x00, 0x00, 0xFA, 0x7F, // 204
+ 0x00, 0x00, 0x00, 0xFA, 0x7F, 0x00, 0x01, // 205
+ 0x02, 0x00, 0x00, 0xF9, 0x7F, 0x00, 0x01, 0x00, 0x00, 0x02, // 206
+ 0x02, 0x00, 0x00, 0xF8, 0x7F, 0x00, 0x02, // 207
+ 0x00, 0x02, 0x00, 0xF8, 0x7F, 0x00, 0x08, 0x42, 0x00, 0x08, 0x42, 0x00, 0x08, 0x42, 0x00, 0x08, 0x42, 0x00, 0x08, 0x40, 0x00, 0x08, 0x40, 0x00, 0x10, 0x20, 0x00, 0x20, 0x10, 0x00, 0xC0, 0x0F, // 208
+ 0x00, 0x00, 0x00, 0xF8, 0x7F, 0x00, 0x10, 0x00, 0x00, 0x60, 0x00, 0x00, 0x82, 0x00, 0x00, 0x01, 0x03, 0x00, 0x02, 0x04, 0x00, 0x01, 0x18, 0x00, 0x00, 0x20, 0x00, 0xF8, 0x7F, // 209
+ 0x00, 0x00, 0x00, 0xC0, 0x0F, 0x00, 0x20, 0x10, 0x00, 0x10, 0x20, 0x00, 0x08, 0x40, 0x00, 0x09, 0x40, 0x00, 0x0A, 0x40, 0x00, 0x08, 0x40, 0x00, 0x10, 0x20, 0x00, 0x20, 0x10, 0x00, 0xC0, 0x0F, // 210
+ 0x00, 0x00, 0x00, 0xC0, 0x0F, 0x00, 0x20, 0x10, 0x00, 0x10, 0x20, 0x00, 0x08, 0x40, 0x00, 0x0A, 0x40, 0x00, 0x09, 0x40, 0x00, 0x08, 0x40, 0x00, 0x10, 0x20, 0x00, 0x20, 0x10, 0x00, 0xC0, 0x0F, // 211
+ 0x00, 0x00, 0x00, 0xC0, 0x0F, 0x00, 0x20, 0x10, 0x00, 0x10, 0x20, 0x00, 0x0A, 0x40, 0x00, 0x09, 0x40, 0x00, 0x09, 0x40, 0x00, 0x0A, 0x40, 0x00, 0x10, 0x20, 0x00, 0x20, 0x10, 0x00, 0xC0, 0x0F, // 212
+ 0x00, 0x00, 0x00, 0xC0, 0x0F, 0x00, 0x20, 0x10, 0x00, 0x10, 0x20, 0x00, 0x0A, 0x40, 0x00, 0x09, 0x40, 0x00, 0x0A, 0x40, 0x00, 0x09, 0x40, 0x00, 0x10, 0x20, 0x00, 0x20, 0x10, 0x00, 0xC0, 0x0F, // 213
+ 0x00, 0x00, 0x00, 0xC0, 0x0F, 0x00, 0x20, 0x10, 0x00, 0x10, 0x20, 0x00, 0x08, 0x40, 0x00, 0x0A, 0x40, 0x00, 0x08, 0x40, 0x00, 0x0A, 0x40, 0x00, 0x10, 0x20, 0x00, 0x20, 0x10, 0x00, 0xC0, 0x0F, // 214
+ 0x00, 0x00, 0x00, 0x40, 0x10, 0x00, 0x80, 0x08, 0x00, 0x00, 0x05, 0x00, 0x00, 0x07, 0x00, 0x00, 0x05, 0x00, 0x80, 0x08, 0x00, 0x40, 0x10, // 215
+ 0x00, 0x00, 0x00, 0xC0, 0x4F, 0x00, 0x20, 0x30, 0x00, 0x10, 0x30, 0x00, 0x08, 0x4C, 0x00, 0x08, 0x42, 0x00, 0x08, 0x41, 0x00, 0xC8, 0x40, 0x00, 0x30, 0x20, 0x00, 0x30, 0x10, 0x00, 0xC8, 0x0F, // 216
+ 0x00, 0x00, 0x00, 0xF8, 0x1F, 0x00, 0x00, 0x20, 0x00, 0x00, 0x40, 0x00, 0x01, 0x40, 0x00, 0x02, 0x40, 0x00, 0x00, 0x40, 0x00, 0x00, 0x40, 0x00, 0x00, 0x20, 0x00, 0xF8, 0x1F, // 217
+ 0x00, 0x00, 0x00, 0xF8, 0x1F, 0x00, 0x00, 0x20, 0x00, 0x00, 0x40, 0x00, 0x00, 0x40, 0x00, 0x02, 0x40, 0x00, 0x01, 0x40, 0x00, 0x00, 0x40, 0x00, 0x00, 0x20, 0x00, 0xF8, 0x1F, // 218
+ 0x00, 0x00, 0x00, 0xF8, 0x1F, 0x00, 0x00, 0x20, 0x00, 0x00, 0x40, 0x00, 0x02, 0x40, 0x00, 0x01, 0x40, 0x00, 0x01, 0x40, 0x00, 0x02, 0x40, 0x00, 0x00, 0x20, 0x00, 0xF8, 0x1F, // 219
+ 0x00, 0x00, 0x00, 0xF8, 0x1F, 0x00, 0x00, 0x20, 0x00, 0x00, 0x40, 0x00, 0x02, 0x40, 0x00, 0x00, 0x40, 0x00, 0x02, 0x40, 0x00, 0x00, 0x40, 0x00, 0x00, 0x20, 0x00, 0xF8, 0x1F, // 220
+ 0x08, 0x00, 0x00, 0x30, 0x00, 0x00, 0x40, 0x00, 0x00, 0x80, 0x01, 0x00, 0x02, 0x7E, 0x00, 0x81, 0x01, 0x00, 0x40, 0x00, 0x00, 0x30, 0x00, 0x00, 0x08, // 221
+ 0x00, 0x00, 0x00, 0xF8, 0x7F, 0x00, 0x20, 0x10, 0x00, 0x20, 0x10, 0x00, 0x20, 0x10, 0x00, 0x20, 0x10, 0x00, 0x20, 0x10, 0x00, 0x20, 0x10, 0x00, 0x40, 0x08, 0x00, 0x80, 0x07, // 222
+ 0x00, 0x00, 0x00, 0xE0, 0x7F, 0x00, 0x10, 0x00, 0x00, 0x08, 0x20, 0x00, 0x88, 0x43, 0x00, 0x70, 0x42, 0x00, 0x00, 0x44, 0x00, 0x00, 0x38, // 223
+ 0x00, 0x00, 0x00, 0x00, 0x39, 0x00, 0x80, 0x44, 0x00, 0x40, 0x44, 0x00, 0x48, 0x44, 0x00, 0x50, 0x42, 0x00, 0x40, 0x22, 0x00, 0x80, 0x7F, // 224
+ 0x00, 0x00, 0x00, 0x00, 0x39, 0x00, 0x80, 0x44, 0x00, 0x40, 0x44, 0x00, 0x50, 0x44, 0x00, 0x48, 0x42, 0x00, 0x40, 0x22, 0x00, 0x80, 0x7F, // 225
+ 0x00, 0x00, 0x00, 0x00, 0x39, 0x00, 0x80, 0x44, 0x00, 0x50, 0x44, 0x00, 0x48, 0x44, 0x00, 0x48, 0x42, 0x00, 0x50, 0x22, 0x00, 0x80, 0x7F, // 226
+ 0x00, 0x00, 0x00, 0x00, 0x39, 0x00, 0x80, 0x44, 0x00, 0x50, 0x44, 0x00, 0x48, 0x44, 0x00, 0x50, 0x42, 0x00, 0x48, 0x22, 0x00, 0x80, 0x7F, // 227
+ 0x00, 0x00, 0x00, 0x00, 0x39, 0x00, 0x80, 0x44, 0x00, 0x50, 0x44, 0x00, 0x40, 0x44, 0x00, 0x50, 0x42, 0x00, 0x40, 0x22, 0x00, 0x80, 0x7F, // 228
+ 0x00, 0x00, 0x00, 0x00, 0x39, 0x00, 0x80, 0x44, 0x00, 0x5C, 0x44, 0x00, 0x54, 0x44, 0x00, 0x5C, 0x42, 0x00, 0x40, 0x22, 0x00, 0x80, 0x7F, // 229
+ 0x00, 0x00, 0x00, 0x00, 0x39, 0x00, 0x80, 0x44, 0x00, 0x40, 0x44, 0x00, 0x40, 0x44, 0x00, 0x40, 0x42, 0x00, 0x40, 0x22, 0x00, 0x80, 0x3F, 0x00, 0x80, 0x24, 0x00, 0x40, 0x44, 0x00, 0x40, 0x44, 0x00, 0x40, 0x44, 0x00, 0x80, 0x24, 0x00, 0x00, 0x17, // 230
+ 0x00, 0x00, 0x00, 0x00, 0x1F, 0x00, 0x80, 0x20, 0x00, 0x40, 0x40, 0x02, 0x40, 0xC0, 0x02, 0x40, 0x40, 0x03, 0x80, 0x20, // 231
+ 0x00, 0x00, 0x00, 0x00, 0x1F, 0x00, 0x80, 0x24, 0x00, 0x48, 0x44, 0x00, 0x50, 0x44, 0x00, 0x40, 0x44, 0x00, 0x80, 0x24, 0x00, 0x00, 0x17, // 232
+ 0x00, 0x00, 0x00, 0x00, 0x1F, 0x00, 0x80, 0x24, 0x00, 0x40, 0x44, 0x00, 0x50, 0x44, 0x00, 0x48, 0x44, 0x00, 0x80, 0x24, 0x00, 0x00, 0x17, // 233
+ 0x00, 0x00, 0x00, 0x00, 0x1F, 0x00, 0x80, 0x24, 0x00, 0x50, 0x44, 0x00, 0x48, 0x44, 0x00, 0x48, 0x44, 0x00, 0x90, 0x24, 0x00, 0x00, 0x17, // 234
+ 0x00, 0x00, 0x00, 0x00, 0x1F, 0x00, 0x80, 0x24, 0x00, 0x50, 0x44, 0x00, 0x40, 0x44, 0x00, 0x50, 0x44, 0x00, 0x80, 0x24, 0x00, 0x00, 0x17, // 235
+ 0x08, 0x00, 0x00, 0xD0, 0x7F, // 236
+ 0x00, 0x00, 0x00, 0xD0, 0x7F, 0x00, 0x08, // 237
+ 0x10, 0x00, 0x00, 0xC8, 0x7F, 0x00, 0x08, 0x00, 0x00, 0x10, // 238
+ 0x10, 0x00, 0x00, 0xC0, 0x7F, 0x00, 0x10, // 239
+ 0x00, 0x00, 0x00, 0x00, 0x1F, 0x00, 0xA0, 0x20, 0x00, 0x68, 0x40, 0x00, 0x58, 0x40, 0x00, 0x70, 0x40, 0x00, 0xE8, 0x20, 0x00, 0x00, 0x1F, // 240
+ 0x00, 0x00, 0x00, 0xC0, 0x7F, 0x00, 0x90, 0x00, 0x00, 0x48, 0x00, 0x00, 0x50, 0x00, 0x00, 0x48, 0x00, 0x00, 0x80, 0x7F, // 241
+ 0x00, 0x00, 0x00, 0x00, 0x1F, 0x00, 0x80, 0x20, 0x00, 0x48, 0x40, 0x00, 0x50, 0x40, 0x00, 0x40, 0x40, 0x00, 0x80, 0x20, 0x00, 0x00, 0x1F, // 242
+ 0x00, 0x00, 0x00, 0x00, 0x1F, 0x00, 0x80, 0x20, 0x00, 0x40, 0x40, 0x00, 0x50, 0x40, 0x00, 0x48, 0x40, 0x00, 0x80, 0x20, 0x00, 0x00, 0x1F, // 243
+ 0x00, 0x00, 0x00, 0x00, 0x1F, 0x00, 0x80, 0x20, 0x00, 0x50, 0x40, 0x00, 0x48, 0x40, 0x00, 0x48, 0x40, 0x00, 0x90, 0x20, 0x00, 0x00, 0x1F, // 244
+ 0x00, 0x00, 0x00, 0x00, 0x1F, 0x00, 0x80, 0x20, 0x00, 0x50, 0x40, 0x00, 0x48, 0x40, 0x00, 0x50, 0x40, 0x00, 0x88, 0x20, 0x00, 0x00, 0x1F, // 245
+ 0x00, 0x00, 0x00, 0x00, 0x1F, 0x00, 0x80, 0x20, 0x00, 0x50, 0x40, 0x00, 0x40, 0x40, 0x00, 0x50, 0x40, 0x00, 0x80, 0x20, 0x00, 0x00, 0x1F, // 246
+ 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x02, 0x00, 0x00, 0x02, 0x00, 0x80, 0x0A, 0x00, 0x00, 0x02, 0x00, 0x00, 0x02, 0x00, 0x00, 0x02, // 247
+ 0x00, 0x00, 0x00, 0x00, 0x5F, 0x00, 0x80, 0x30, 0x00, 0x40, 0x48, 0x00, 0x40, 0x44, 0x00, 0x40, 0x42, 0x00, 0x80, 0x21, 0x00, 0x40, 0x1F, // 248
+ 0x00, 0x00, 0x00, 0xC0, 0x3F, 0x00, 0x00, 0x40, 0x00, 0x08, 0x40, 0x00, 0x10, 0x40, 0x00, 0x00, 0x20, 0x00, 0xC0, 0x7F, // 249
+ 0x00, 0x00, 0x00, 0xC0, 0x3F, 0x00, 0x00, 0x40, 0x00, 0x00, 0x40, 0x00, 0x10, 0x40, 0x00, 0x08, 0x20, 0x00, 0xC0, 0x7F, // 250
+ 0x00, 0x00, 0x00, 0xC0, 0x3F, 0x00, 0x10, 0x40, 0x00, 0x08, 0x40, 0x00, 0x08, 0x40, 0x00, 0x10, 0x20, 0x00, 0xC0, 0x7F, // 251
+ 0x00, 0x00, 0x00, 0xD0, 0x3F, 0x00, 0x00, 0x40, 0x00, 0x10, 0x40, 0x00, 0x00, 0x40, 0x00, 0x00, 0x20, 0x00, 0xC0, 0x7F, // 252
+ 0xC0, 0x01, 0x00, 0x00, 0x06, 0x02, 0x00, 0x38, 0x02, 0x10, 0xE0, 0x01, 0x08, 0x38, 0x00, 0x00, 0x07, 0x00, 0xC0, // 253
+ 0x00, 0x00, 0x00, 0xF8, 0xFF, 0x03, 0x80, 0x20, 0x00, 0x40, 0x40, 0x00, 0x40, 0x40, 0x00, 0x40, 0x40, 0x00, 0x80, 0x20, 0x00, 0x00, 0x1F, // 254
+ 0xC0, 0x01, 0x00, 0x00, 0x06, 0x02, 0x10, 0x38, 0x02, 0x00, 0xE0, 0x01, 0x10, 0x38, 0x00, 0x00, 0x07, 0x00, 0xC0, // 255
};
const uint8_t ArialMT_Plain_24_PL[] PROGMEM = {
-0x18, // Width: 24
-0x1C, // Height: 28
-0x20, // First char: 32
-0xE0, // Number of chars: 224
-// Jump Table:
-0xFF, 0xFF, 0x00, 0x06, // 32
-0x00, 0x00, 0x13, 0x06, // 33
-0x00, 0x13, 0x1A, 0x08, // 34
-0x00, 0x2D, 0x33, 0x0E, // 35
-0x00, 0x60, 0x2F, 0x0D, // 36
-0x00, 0x8F, 0x4F, 0x15, // 37
-0x00, 0xDE, 0x3B, 0x10, // 38
-0x01, 0x19, 0x0A, 0x04, // 39
-0x01, 0x23, 0x1C, 0x08, // 40
-0x01, 0x3F, 0x1B, 0x08, // 41
-0x01, 0x5A, 0x21, 0x0A, // 42
-0x01, 0x7B, 0x32, 0x0E, // 43
-0x01, 0xAD, 0x10, 0x05, // 44
-0x01, 0xBD, 0x1B, 0x08, // 45
-0x01, 0xD8, 0x0F, 0x05, // 46
-0x01, 0xE7, 0x19, 0x08, // 47
-0x02, 0x00, 0x2F, 0x0D, // 48
-0x02, 0x2F, 0x23, 0x0A, // 49
-0x02, 0x52, 0x2F, 0x0D, // 50
-0x02, 0x81, 0x2F, 0x0D, // 51
-0x02, 0xB0, 0x2F, 0x0D, // 52
-0x02, 0xDF, 0x2F, 0x0D, // 53
-0x03, 0x0E, 0x2F, 0x0D, // 54
-0x03, 0x3D, 0x2D, 0x0D, // 55
-0x03, 0x6A, 0x2F, 0x0D, // 56
-0x03, 0x99, 0x2F, 0x0D, // 57
-0x03, 0xC8, 0x0F, 0x05, // 58
-0x03, 0xD7, 0x10, 0x05, // 59
-0x03, 0xE7, 0x2F, 0x0D, // 60
-0x04, 0x16, 0x2F, 0x0D, // 61
-0x04, 0x45, 0x2E, 0x0D, // 62
-0x04, 0x73, 0x2E, 0x0D, // 63
-0x04, 0xA1, 0x5B, 0x18, // 64
-0x04, 0xFC, 0x3B, 0x10, // 65
-0x05, 0x37, 0x3B, 0x10, // 66
-0x05, 0x72, 0x3F, 0x11, // 67
-0x05, 0xB1, 0x3F, 0x11, // 68
-0x05, 0xF0, 0x3B, 0x10, // 69
-0x06, 0x2B, 0x35, 0x0F, // 70
-0x06, 0x60, 0x43, 0x12, // 71
-0x06, 0xA3, 0x3B, 0x10, // 72
-0x06, 0xDE, 0x0F, 0x05, // 73
-0x06, 0xED, 0x27, 0x0B, // 74
-0x07, 0x14, 0x3F, 0x11, // 75
-0x07, 0x53, 0x2F, 0x0D, // 76
-0x07, 0x82, 0x43, 0x12, // 77
-0x07, 0xC5, 0x3B, 0x10, // 78
-0x08, 0x00, 0x47, 0x13, // 79
-0x08, 0x47, 0x3A, 0x10, // 80
-0x08, 0x81, 0x47, 0x13, // 81
-0x08, 0xC8, 0x3F, 0x11, // 82
-0x09, 0x07, 0x3B, 0x10, // 83
-0x09, 0x42, 0x35, 0x0F, // 84
-0x09, 0x77, 0x3B, 0x10, // 85
-0x09, 0xB2, 0x39, 0x10, // 86
-0x09, 0xEB, 0x59, 0x18, // 87
-0x0A, 0x44, 0x3B, 0x10, // 88
-0x0A, 0x7F, 0x3D, 0x11, // 89
-0x0A, 0xBC, 0x37, 0x0F, // 90
-0x0A, 0xF3, 0x14, 0x06, // 91
-0x0B, 0x07, 0x1B, 0x08, // 92
-0x0B, 0x22, 0x18, 0x07, // 93
-0x0B, 0x3A, 0x2A, 0x0C, // 94
-0x0B, 0x64, 0x34, 0x0E, // 95
-0x0B, 0x98, 0x11, 0x06, // 96
-0x0B, 0xA9, 0x2F, 0x0D, // 97
-0x0B, 0xD8, 0x33, 0x0E, // 98
-0x0C, 0x0B, 0x2B, 0x0C, // 99
-0x0C, 0x36, 0x2F, 0x0D, // 100
-0x0C, 0x65, 0x2F, 0x0D, // 101
-0x0C, 0x94, 0x1A, 0x08, // 102
-0x0C, 0xAE, 0x2F, 0x0D, // 103
-0x0C, 0xDD, 0x2F, 0x0D, // 104
-0x0D, 0x0C, 0x0F, 0x05, // 105
-0x0D, 0x1B, 0x10, 0x05, // 106
-0x0D, 0x2B, 0x2F, 0x0D, // 107
-0x0D, 0x5A, 0x0F, 0x05, // 108
-0x0D, 0x69, 0x47, 0x13, // 109
-0x0D, 0xB0, 0x2F, 0x0D, // 110
-0x0D, 0xDF, 0x2F, 0x0D, // 111
-0x0E, 0x0E, 0x33, 0x0E, // 112
-0x0E, 0x41, 0x30, 0x0D, // 113
-0x0E, 0x71, 0x1E, 0x09, // 114
-0x0E, 0x8F, 0x2B, 0x0C, // 115
-0x0E, 0xBA, 0x1B, 0x08, // 116
-0x0E, 0xD5, 0x2F, 0x0D, // 117
-0x0F, 0x04, 0x2A, 0x0C, // 118
-0x0F, 0x2E, 0x42, 0x12, // 119
-0x0F, 0x70, 0x2B, 0x0C, // 120
-0x0F, 0x9B, 0x2A, 0x0C, // 121
-0x0F, 0xC5, 0x2B, 0x0C, // 122
-0x0F, 0xF0, 0x1C, 0x08, // 123
-0x10, 0x0C, 0x10, 0x05, // 124
-0x10, 0x1C, 0x1B, 0x08, // 125
-0x10, 0x37, 0x32, 0x0E, // 126
-0xFF, 0xFF, 0x00, 0x18, // 127
-0xFF, 0xFF, 0x00, 0x18, // 128
-0x10, 0x69, 0x2F, 0x0D, // 129
-0x10, 0x98, 0x16, 0x07, // 130
-0x10, 0xAE, 0x3B, 0x10, // 131
-0x10, 0xE9, 0x40, 0x11, // 132
-0x11, 0x29, 0x34, 0x0E, // 133
-0x11, 0x5D, 0x3F, 0x11, // 134
-0x11, 0x9C, 0x2B, 0x0C, // 135
-0x11, 0xC7, 0x2F, 0x0D, // 136
-0x11, 0xF6, 0x2B, 0x0C, // 137
-0xFF, 0xFF, 0x00, 0x18, // 138
-0xFF, 0xFF, 0x00, 0x18, // 139
-0xFF, 0xFF, 0x00, 0x18, // 140
-0xFF, 0xFF, 0x00, 0x18, // 141
-0xFF, 0xFF, 0x00, 0x18, // 142
-0xFF, 0xFF, 0x00, 0x18, // 143
-0xFF, 0xFF, 0x00, 0x18, // 144
-0xFF, 0xFF, 0x00, 0x18, // 145
-0xFF, 0xFF, 0x00, 0x18, // 146
-0x12, 0x21, 0x47, 0x13, // 147
-0x12, 0x68, 0x2F, 0x0D, // 148
-0xFF, 0xFF, 0x00, 0x18, // 149
-0xFF, 0xFF, 0x00, 0x18, // 150
-0xFF, 0xFF, 0x00, 0x18, // 151
-0x12, 0x97, 0x3B, 0x10, // 152
-0x12, 0xD2, 0x2F, 0x0D, // 153
-0x13, 0x01, 0x3B, 0x10, // 154
-0x13, 0x3C, 0x2B, 0x0C, // 155
-0xFF, 0xFF, 0x00, 0x18, // 156
-0xFF, 0xFF, 0x00, 0x18, // 157
-0xFF, 0xFF, 0x00, 0x18, // 158
-0xFF, 0xFF, 0x00, 0x18, // 159
-0xFF, 0xFF, 0x00, 0x18, // 160
-0x13, 0x67, 0x14, 0x06, // 161
-0x13, 0x7B, 0x2B, 0x0C, // 162
-0x13, 0xA6, 0x2F, 0x0D, // 163
-0x13, 0xD5, 0x33, 0x0E, // 164
-0x14, 0x08, 0x31, 0x0E, // 165
-0x14, 0x39, 0x10, 0x05, // 166
-0x14, 0x49, 0x2F, 0x0D, // 167
-0x14, 0x78, 0x19, 0x08, // 168
-0x14, 0x91, 0x46, 0x13, // 169
-0x14, 0xD7, 0x1A, 0x08, // 170
-0x14, 0xF1, 0x27, 0x0B, // 171
-0x15, 0x18, 0x2F, 0x0D, // 172
-0x15, 0x47, 0x1B, 0x08, // 173
-0x15, 0x62, 0x46, 0x13, // 174
-0x15, 0xA8, 0x31, 0x0E, // 175
-0x15, 0xD9, 0x1E, 0x09, // 176
-0x15, 0xF7, 0x33, 0x0E, // 177
-0x16, 0x2A, 0x1A, 0x08, // 178
-0x16, 0x44, 0x1A, 0x08, // 179
-0x16, 0x5E, 0x19, 0x08, // 180
-0x16, 0x77, 0x2F, 0x0D, // 181
-0x16, 0xA6, 0x31, 0x0E, // 182
-0x16, 0xD7, 0x12, 0x06, // 183
-0x16, 0xE9, 0x18, 0x07, // 184
-0x17, 0x01, 0x37, 0x0F, // 185
-0x17, 0x38, 0x1E, 0x09, // 186
-0x17, 0x56, 0x37, 0x0F, // 187
-0x17, 0x8D, 0x2B, 0x0C, // 188
-0x17, 0xB8, 0x4B, 0x14, // 189
-0x18, 0x03, 0x4B, 0x14, // 190
-0x18, 0x4E, 0x33, 0x0E, // 191
-0x18, 0x81, 0x3B, 0x10, // 192
-0x18, 0xBC, 0x3B, 0x10, // 193
-0x18, 0xF7, 0x3B, 0x10, // 194
-0x19, 0x32, 0x3B, 0x10, // 195
-0x19, 0x6D, 0x3B, 0x10, // 196
-0x19, 0xA8, 0x3B, 0x10, // 197
-0x19, 0xE3, 0x5B, 0x18, // 198
-0x1A, 0x3E, 0x3F, 0x11, // 199
-0x1A, 0x7D, 0x3B, 0x10, // 200
-0x1A, 0xB8, 0x3B, 0x10, // 201
-0x1A, 0xF3, 0x3B, 0x10, // 202
-0x1B, 0x2E, 0x3B, 0x10, // 203
-0x1B, 0x69, 0x11, 0x06, // 204
-0x1B, 0x7A, 0x11, 0x06, // 205
-0x1B, 0x8B, 0x15, 0x07, // 206
-0x1B, 0xA0, 0x15, 0x07, // 207
-0x1B, 0xB5, 0x3F, 0x11, // 208
-0x1B, 0xF4, 0x3B, 0x10, // 209
-0x1C, 0x2F, 0x47, 0x13, // 210
-0x1C, 0x76, 0x47, 0x13, // 211
-0x1C, 0xBD, 0x47, 0x13, // 212
-0x1D, 0x04, 0x47, 0x13, // 213
-0x1D, 0x4B, 0x47, 0x13, // 214
-0x1D, 0x92, 0x2B, 0x0C, // 215
-0x1D, 0xBD, 0x47, 0x13, // 216
-0x1E, 0x04, 0x3B, 0x10, // 217
-0x1E, 0x3F, 0x3B, 0x10, // 218
-0x1E, 0x7A, 0x3B, 0x10, // 219
-0x1E, 0xB5, 0x3B, 0x10, // 220
-0x1E, 0xF0, 0x3D, 0x11, // 221
-0x1F, 0x2D, 0x3A, 0x10, // 222
-0x1F, 0x67, 0x37, 0x0F, // 223
-0x1F, 0x9E, 0x2F, 0x0D, // 224
-0x1F, 0xCD, 0x2F, 0x0D, // 225
-0x1F, 0xFC, 0x2F, 0x0D, // 226
-0x20, 0x2B, 0x2F, 0x0D, // 227
-0x20, 0x5A, 0x2F, 0x0D, // 228
-0x20, 0x89, 0x2F, 0x0D, // 229
-0x20, 0xB8, 0x53, 0x16, // 230
-0x21, 0x0B, 0x2B, 0x0C, // 231
-0x21, 0x36, 0x2F, 0x0D, // 232
-0x21, 0x65, 0x2F, 0x0D, // 233
-0x21, 0x94, 0x2F, 0x0D, // 234
-0x21, 0xC3, 0x2F, 0x0D, // 235
-0x21, 0xF2, 0x11, 0x06, // 236
-0x22, 0x03, 0x11, 0x06, // 237
-0x22, 0x14, 0x15, 0x07, // 238
-0x22, 0x29, 0x15, 0x07, // 239
-0x22, 0x3E, 0x2F, 0x0D, // 240
-0x22, 0x6D, 0x2F, 0x0D, // 241
-0x22, 0x9C, 0x2F, 0x0D, // 242
-0x22, 0xCB, 0x2F, 0x0D, // 243
-0x22, 0xFA, 0x2F, 0x0D, // 244
-0x23, 0x29, 0x2F, 0x0D, // 245
-0x23, 0x58, 0x2F, 0x0D, // 246
-0x23, 0x87, 0x32, 0x0E, // 247
-0x23, 0xB9, 0x33, 0x0E, // 248
-0x23, 0xEC, 0x2F, 0x0D, // 249
-0x24, 0x1B, 0x2F, 0x0D, // 250
-0x24, 0x4A, 0x2F, 0x0D, // 251
-0x24, 0x79, 0x2F, 0x0D, // 252
-0x24, 0xA8, 0x2A, 0x0C, // 253
-0x24, 0xD2, 0x2F, 0x0D, // 254
-0x25, 0x01, 0x2A, 0x0C, // 255
-// Font Data:
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0xFF, 0x33, 0x00, 0xE0, 0xFF, 0x33, // 33
-0x00, 0x00, 0x00, 0x00, 0xE0, 0x07, 0x00, 0x00, 0xE0, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0x07, 0x00, 0x00, 0xE0, 0x07, // 34
-0x00, 0x0C, 0x03, 0x00, 0x00, 0x0C, 0x33, 0x00, 0x00, 0x0C, 0x3F, 0x00, 0x00, 0xFC, 0x0F, 0x00, 0x80, 0xFF, 0x03, 0x00, 0xE0, 0x0F, 0x03, 0x00, 0x60, 0x0C, 0x33, 0x00, 0x00, 0x0C, 0x3F, 0x00, 0x00, 0xFC, 0x0F, 0x00, 0x80, 0xFF, 0x03, 0x00, 0xE0, 0x0F, 0x03, 0x00, 0x60, 0x0C, 0x03, 0x00, 0x00, 0x0C, 0x03, // 35
-0x00, 0x00, 0x00, 0x00, 0x80, 0x07, 0x06, 0x00, 0xC0, 0x0F, 0x1E, 0x00, 0xC0, 0x18, 0x1C, 0x00, 0x60, 0x18, 0x38, 0x00, 0x60, 0x30, 0x30, 0x00, 0xF0, 0xFF, 0xFF, 0x00, 0x60, 0x30, 0x30, 0x00, 0x60, 0x60, 0x38, 0x00, 0xC0, 0x60, 0x18, 0x00, 0xC0, 0xC1, 0x1F, 0x00, 0x00, 0x81, 0x07, // 36
-0x00, 0x00, 0x00, 0x00, 0x80, 0x0F, 0x00, 0x00, 0xC0, 0x1F, 0x00, 0x00, 0x60, 0x30, 0x00, 0x00, 0x20, 0x20, 0x00, 0x00, 0x20, 0x20, 0x20, 0x00, 0x60, 0x30, 0x38, 0x00, 0xC0, 0x1F, 0x1E, 0x00, 0x80, 0x8F, 0x0F, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0xF0, 0x00, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x00, 0x8F, 0x0F, 0x00, 0xC0, 0xC3, 0x1F, 0x00, 0xE0, 0x60, 0x30, 0x00, 0x20, 0x20, 0x20, 0x00, 0x00, 0x20, 0x20, 0x00, 0x00, 0x60, 0x30, 0x00, 0x00, 0xC0, 0x1F, 0x00, 0x00, 0x80, 0x0F, // 37
-0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x07, 0x00, 0x00, 0xC0, 0x0F, 0x00, 0x80, 0xE3, 0x1C, 0x00, 0xC0, 0x77, 0x38, 0x00, 0xE0, 0x3C, 0x30, 0x00, 0x60, 0x38, 0x30, 0x00, 0x60, 0x78, 0x30, 0x00, 0xE0, 0xEC, 0x38, 0x00, 0xC0, 0x8F, 0x1B, 0x00, 0x80, 0x03, 0x1F, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0xC0, 0x1F, 0x00, 0x00, 0xC0, 0x38, 0x00, 0x00, 0x00, 0x10, // 38
-0x00, 0x00, 0x00, 0x00, 0xE0, 0x07, 0x00, 0x00, 0xE0, 0x07, // 39
-0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x0F, 0x00, 0x00, 0xFE, 0x7F, 0x00, 0x80, 0x0F, 0xF0, 0x01, 0xC0, 0x01, 0x80, 0x03, 0x60, 0x00, 0x00, 0x06, 0x20, 0x00, 0x00, 0x04, // 40
-0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x04, 0x60, 0x00, 0x00, 0x06, 0xC0, 0x01, 0x80, 0x03, 0x80, 0x0F, 0xF0, 0x01, 0x00, 0xFE, 0x7F, 0x00, 0x00, 0xF0, 0x0F, // 41
-0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x04, 0x00, 0x00, 0x80, 0x0F, 0x00, 0x00, 0xE0, 0x03, 0x00, 0x00, 0xE0, 0x03, 0x00, 0x00, 0x80, 0x0F, 0x00, 0x00, 0x80, 0x04, 0x00, 0x00, 0x80, // 42
-0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0xFF, 0x0F, 0x00, 0x00, 0xFF, 0x0F, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x60, // 43
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x03, 0x00, 0x00, 0xF0, 0x01, // 44
-0x00, 0x80, 0x01, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x80, 0x01, // 45
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x30, // 46
-0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x3E, 0x00, 0x00, 0xE0, 0x0F, 0x00, 0x00, 0xFC, 0x01, 0x00, 0x80, 0x3F, 0x00, 0x00, 0xE0, 0x03, 0x00, 0x00, 0x60, // 47
-0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0x03, 0x00, 0x80, 0xFF, 0x0F, 0x00, 0xC0, 0x01, 0x1C, 0x00, 0xE0, 0x00, 0x38, 0x00, 0x60, 0x00, 0x30, 0x00, 0x60, 0x00, 0x30, 0x00, 0x60, 0x00, 0x30, 0x00, 0xE0, 0x00, 0x38, 0x00, 0xC0, 0x01, 0x1C, 0x00, 0x80, 0xFF, 0x0F, 0x00, 0x00, 0xFE, 0x03, // 48
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0xE0, 0xFF, 0x3F, 0x00, 0xE0, 0xFF, 0x3F, // 49
-0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x30, 0x00, 0xC0, 0x03, 0x38, 0x00, 0xC0, 0x00, 0x3C, 0x00, 0x60, 0x00, 0x36, 0x00, 0x60, 0x00, 0x33, 0x00, 0x60, 0x80, 0x31, 0x00, 0x60, 0xC0, 0x30, 0x00, 0x60, 0x60, 0x30, 0x00, 0xC0, 0x30, 0x30, 0x00, 0xC0, 0x1F, 0x30, 0x00, 0x00, 0x0F, 0x30, // 50
-0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x06, 0x00, 0xC0, 0x01, 0x0E, 0x00, 0xC0, 0x00, 0x1C, 0x00, 0x60, 0x00, 0x30, 0x00, 0x60, 0x30, 0x30, 0x00, 0x60, 0x30, 0x30, 0x00, 0x60, 0x30, 0x30, 0x00, 0xC0, 0x38, 0x30, 0x00, 0xC0, 0x6F, 0x18, 0x00, 0x80, 0xC7, 0x0F, 0x00, 0x00, 0x80, 0x07, // 51
-0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x03, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0xF0, 0x03, 0x00, 0x00, 0x3C, 0x03, 0x00, 0x00, 0x0E, 0x03, 0x00, 0x80, 0x07, 0x03, 0x00, 0xC0, 0x01, 0x03, 0x00, 0xE0, 0xFF, 0x3F, 0x00, 0xE0, 0xFF, 0x3F, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, // 52
-0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x06, 0x00, 0x80, 0x3F, 0x0E, 0x00, 0xE0, 0x1F, 0x18, 0x00, 0x60, 0x08, 0x30, 0x00, 0x60, 0x0C, 0x30, 0x00, 0x60, 0x0C, 0x30, 0x00, 0x60, 0x0C, 0x30, 0x00, 0x60, 0x0C, 0x30, 0x00, 0x60, 0x18, 0x1C, 0x00, 0x60, 0xF0, 0x0F, 0x00, 0x00, 0xE0, 0x03, // 53
-0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 0x03, 0x00, 0x80, 0xFF, 0x0F, 0x00, 0xC0, 0x63, 0x1C, 0x00, 0xC0, 0x30, 0x38, 0x00, 0x60, 0x18, 0x30, 0x00, 0x60, 0x18, 0x30, 0x00, 0x60, 0x18, 0x30, 0x00, 0x60, 0x18, 0x30, 0x00, 0xE0, 0x30, 0x18, 0x00, 0xC0, 0xF1, 0x0F, 0x00, 0x80, 0xC1, 0x07, // 54
-0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x60, 0x00, 0x3C, 0x00, 0x60, 0x80, 0x3F, 0x00, 0x60, 0xE0, 0x03, 0x00, 0x60, 0x78, 0x00, 0x00, 0x60, 0x0E, 0x00, 0x00, 0x60, 0x03, 0x00, 0x00, 0xE0, 0x01, 0x00, 0x00, 0x60, // 55
-0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x07, 0x00, 0x80, 0xC7, 0x1F, 0x00, 0xC0, 0x6F, 0x18, 0x00, 0xE0, 0x38, 0x30, 0x00, 0x60, 0x30, 0x30, 0x00, 0x60, 0x30, 0x30, 0x00, 0x60, 0x30, 0x30, 0x00, 0xE0, 0x38, 0x30, 0x00, 0xC0, 0x6F, 0x18, 0x00, 0x80, 0xC7, 0x1F, 0x00, 0x00, 0x80, 0x07, // 56
-0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x0C, 0x00, 0x80, 0x7F, 0x1C, 0x00, 0xC0, 0x61, 0x38, 0x00, 0x60, 0xC0, 0x30, 0x00, 0x60, 0xC0, 0x30, 0x00, 0x60, 0xC0, 0x30, 0x00, 0x60, 0xC0, 0x30, 0x00, 0x60, 0x60, 0x18, 0x00, 0xC0, 0x31, 0x1E, 0x00, 0x80, 0xFF, 0x0F, 0x00, 0x00, 0xFE, 0x01, // 57
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x30, 0x00, 0x00, 0x06, 0x30, // 58
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x30, 0x03, 0x00, 0x06, 0xF0, 0x01, // 59
-0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0xD8, 0x00, 0x00, 0x00, 0xD8, 0x00, 0x00, 0x00, 0x8C, 0x01, 0x00, 0x00, 0x8C, 0x01, 0x00, 0x00, 0x04, 0x01, 0x00, 0x00, 0x06, 0x03, 0x00, 0x00, 0x06, 0x03, 0x00, 0x00, 0x03, 0x06, // 60
-0x00, 0x00, 0x00, 0x00, 0x00, 0x8C, 0x01, 0x00, 0x00, 0x8C, 0x01, 0x00, 0x00, 0x8C, 0x01, 0x00, 0x00, 0x8C, 0x01, 0x00, 0x00, 0x8C, 0x01, 0x00, 0x00, 0x8C, 0x01, 0x00, 0x00, 0x8C, 0x01, 0x00, 0x00, 0x8C, 0x01, 0x00, 0x00, 0x8C, 0x01, 0x00, 0x00, 0x8C, 0x01, 0x00, 0x00, 0x8C, 0x01, // 61
-0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x06, 0x00, 0x00, 0x06, 0x03, 0x00, 0x00, 0x06, 0x03, 0x00, 0x00, 0x04, 0x01, 0x00, 0x00, 0x8C, 0x01, 0x00, 0x00, 0x8C, 0x01, 0x00, 0x00, 0xD8, 0x00, 0x00, 0x00, 0xD8, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x20, // 62
-0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x80, 0x03, 0x00, 0x00, 0xC0, 0x01, 0x00, 0x00, 0xE0, 0x00, 0x00, 0x00, 0x60, 0x80, 0x33, 0x00, 0x60, 0xC0, 0x33, 0x00, 0x60, 0xE0, 0x00, 0x00, 0x60, 0x30, 0x00, 0x00, 0xC0, 0x38, 0x00, 0x00, 0xC0, 0x1F, 0x00, 0x00, 0x00, 0x07, // 63
-0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0x0F, 0x00, 0x00, 0xF8, 0x3F, 0x00, 0x00, 0x1E, 0xF0, 0x00, 0x00, 0x07, 0xC0, 0x01, 0x80, 0xC3, 0x87, 0x01, 0xC0, 0xF1, 0x9F, 0x03, 0xC0, 0x38, 0x18, 0x03, 0xC0, 0x0C, 0x30, 0x03, 0x60, 0x0E, 0x30, 0x06, 0x60, 0x06, 0x30, 0x06, 0x60, 0x06, 0x18, 0x06, 0x60, 0x06, 0x0C, 0x06, 0x60, 0x0C, 0x1E, 0x06, 0x60, 0xF8, 0x3F, 0x06, 0xE0, 0xFE, 0x31, 0x06, 0xC0, 0x0E, 0x30, 0x06, 0xC0, 0x01, 0x18, 0x03, 0x80, 0x03, 0x1C, 0x03, 0x00, 0x07, 0x8F, 0x01, 0x00, 0xFE, 0x87, 0x01, 0x00, 0xF8, 0xC1, 0x00, 0x00, 0x00, 0x40, // 64
-0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x3E, 0x00, 0x00, 0x80, 0x0F, 0x00, 0x00, 0xF0, 0x03, 0x00, 0x00, 0xFE, 0x01, 0x00, 0x80, 0x8F, 0x01, 0x00, 0xE0, 0x83, 0x01, 0x00, 0x60, 0x80, 0x01, 0x00, 0xE0, 0x83, 0x01, 0x00, 0x80, 0x8F, 0x01, 0x00, 0x00, 0xFE, 0x01, 0x00, 0x00, 0xF0, 0x03, 0x00, 0x00, 0x80, 0x0F, 0x00, 0x00, 0x00, 0x3E, 0x00, 0x00, 0x00, 0x30, // 65
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0xFF, 0x3F, 0x00, 0xE0, 0xFF, 0x3F, 0x00, 0x60, 0x30, 0x30, 0x00, 0x60, 0x30, 0x30, 0x00, 0x60, 0x30, 0x30, 0x00, 0x60, 0x30, 0x30, 0x00, 0x60, 0x30, 0x30, 0x00, 0x60, 0x30, 0x30, 0x00, 0x60, 0x30, 0x30, 0x00, 0xC0, 0x78, 0x30, 0x00, 0xC0, 0xFF, 0x18, 0x00, 0x80, 0xC7, 0x1F, 0x00, 0x00, 0x80, 0x07, // 66
-0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 0x01, 0x00, 0x00, 0xFF, 0x07, 0x00, 0x80, 0x07, 0x0F, 0x00, 0xC0, 0x01, 0x1C, 0x00, 0xC0, 0x00, 0x18, 0x00, 0x60, 0x00, 0x30, 0x00, 0x60, 0x00, 0x30, 0x00, 0x60, 0x00, 0x30, 0x00, 0x60, 0x00, 0x30, 0x00, 0x60, 0x00, 0x30, 0x00, 0x60, 0x00, 0x30, 0x00, 0xC0, 0x00, 0x18, 0x00, 0xC0, 0x01, 0x1C, 0x00, 0x80, 0x03, 0x0F, 0x00, 0x00, 0x02, 0x03, // 67
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0xFF, 0x3F, 0x00, 0xE0, 0xFF, 0x3F, 0x00, 0x60, 0x00, 0x30, 0x00, 0x60, 0x00, 0x30, 0x00, 0x60, 0x00, 0x30, 0x00, 0x60, 0x00, 0x30, 0x00, 0x60, 0x00, 0x30, 0x00, 0x60, 0x00, 0x30, 0x00, 0x60, 0x00, 0x30, 0x00, 0xE0, 0x00, 0x18, 0x00, 0xC0, 0x01, 0x1C, 0x00, 0x80, 0x03, 0x0E, 0x00, 0x00, 0xFF, 0x07, 0x00, 0x00, 0xFC, 0x01, // 68
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0xFF, 0x3F, 0x00, 0xE0, 0xFF, 0x3F, 0x00, 0x60, 0x30, 0x30, 0x00, 0x60, 0x30, 0x30, 0x00, 0x60, 0x30, 0x30, 0x00, 0x60, 0x30, 0x30, 0x00, 0x60, 0x30, 0x30, 0x00, 0x60, 0x30, 0x30, 0x00, 0x60, 0x30, 0x30, 0x00, 0x60, 0x30, 0x30, 0x00, 0x60, 0x30, 0x30, 0x00, 0x60, 0x30, 0x30, 0x00, 0x60, 0x00, 0x30, // 69
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0xFF, 0x3F, 0x00, 0xE0, 0xFF, 0x3F, 0x00, 0x60, 0x30, 0x00, 0x00, 0x60, 0x30, 0x00, 0x00, 0x60, 0x30, 0x00, 0x00, 0x60, 0x30, 0x00, 0x00, 0x60, 0x30, 0x00, 0x00, 0x60, 0x30, 0x00, 0x00, 0x60, 0x30, 0x00, 0x00, 0x60, 0x30, 0x00, 0x00, 0x60, 0x30, 0x00, 0x00, 0x60, // 70
-0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 0x01, 0x00, 0x00, 0xFF, 0x07, 0x00, 0x80, 0x07, 0x0F, 0x00, 0xC0, 0x01, 0x1C, 0x00, 0xC0, 0x00, 0x18, 0x00, 0xE0, 0x00, 0x18, 0x00, 0x60, 0x00, 0x30, 0x00, 0x60, 0x00, 0x30, 0x00, 0x60, 0x00, 0x30, 0x00, 0x60, 0x60, 0x30, 0x00, 0x60, 0x60, 0x30, 0x00, 0xE0, 0x60, 0x38, 0x00, 0xC0, 0x60, 0x18, 0x00, 0xC0, 0x61, 0x18, 0x00, 0x80, 0xE3, 0x0F, 0x00, 0x00, 0xE2, 0x0F, // 71
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0xFF, 0x3F, 0x00, 0xE0, 0xFF, 0x3F, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0xE0, 0xFF, 0x3F, 0x00, 0xE0, 0xFF, 0x3F, // 72
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0xFF, 0x3F, 0x00, 0xE0, 0xFF, 0x3F, // 73
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x1E, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x38, 0x00, 0xE0, 0xFF, 0x1F, 0x00, 0xE0, 0xFF, 0x0F, // 74
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0xFF, 0x3F, 0x00, 0xE0, 0xFF, 0x3F, 0x00, 0x00, 0xE0, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x7C, 0x00, 0x00, 0x00, 0xFE, 0x00, 0x00, 0x00, 0xE7, 0x01, 0x00, 0x80, 0x83, 0x07, 0x00, 0xC0, 0x01, 0x0F, 0x00, 0xE0, 0x00, 0x1E, 0x00, 0x60, 0x00, 0x38, 0x00, 0x20, 0x00, 0x30, 0x00, 0x00, 0x00, 0x20, // 75
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0xFF, 0x3F, 0x00, 0xE0, 0xFF, 0x3F, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x30, // 76
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0xFF, 0x3F, 0x00, 0xE0, 0xFF, 0x3F, 0x00, 0xE0, 0x01, 0x00, 0x00, 0xC0, 0x0F, 0x00, 0x00, 0x00, 0xFE, 0x00, 0x00, 0x00, 0xE0, 0x07, 0x00, 0x00, 0x00, 0x3F, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x3F, 0x00, 0x00, 0xE0, 0x07, 0x00, 0x00, 0xFE, 0x00, 0x00, 0xC0, 0x0F, 0x00, 0x00, 0xE0, 0x01, 0x00, 0x00, 0xE0, 0xFF, 0x3F, 0x00, 0xE0, 0xFF, 0x3F, // 77
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0xFF, 0x3F, 0x00, 0xE0, 0xFF, 0x3F, 0x00, 0xC0, 0x01, 0x00, 0x00, 0x80, 0x03, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0xE0, 0x01, 0x00, 0x00, 0x80, 0x03, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x1C, 0x00, 0xE0, 0xFF, 0x3F, 0x00, 0xE0, 0xFF, 0x3F, // 78
-0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 0x01, 0x00, 0x00, 0xFF, 0x07, 0x00, 0x80, 0x07, 0x0F, 0x00, 0xC0, 0x01, 0x1C, 0x00, 0xC0, 0x00, 0x18, 0x00, 0xE0, 0x00, 0x38, 0x00, 0x60, 0x00, 0x30, 0x00, 0x60, 0x00, 0x30, 0x00, 0x60, 0x00, 0x30, 0x00, 0x60, 0x00, 0x30, 0x00, 0x60, 0x00, 0x30, 0x00, 0xE0, 0x00, 0x38, 0x00, 0xC0, 0x00, 0x18, 0x00, 0xC0, 0x01, 0x1C, 0x00, 0x80, 0x07, 0x0F, 0x00, 0x00, 0xFF, 0x07, 0x00, 0x00, 0xFC, 0x01, // 79
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0xFF, 0x3F, 0x00, 0xE0, 0xFF, 0x3F, 0x00, 0x60, 0x60, 0x00, 0x00, 0x60, 0x60, 0x00, 0x00, 0x60, 0x60, 0x00, 0x00, 0x60, 0x60, 0x00, 0x00, 0x60, 0x60, 0x00, 0x00, 0x60, 0x60, 0x00, 0x00, 0x60, 0x60, 0x00, 0x00, 0x60, 0x60, 0x00, 0x00, 0xC0, 0x30, 0x00, 0x00, 0xC0, 0x3F, 0x00, 0x00, 0x00, 0x0F, // 80
-0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 0x01, 0x00, 0x00, 0xFF, 0x07, 0x00, 0x80, 0x07, 0x0F, 0x00, 0xC0, 0x01, 0x0C, 0x00, 0xC0, 0x00, 0x18, 0x00, 0xE0, 0x00, 0x18, 0x00, 0x60, 0x00, 0x30, 0x00, 0x60, 0x00, 0x30, 0x00, 0x60, 0x00, 0x30, 0x00, 0x60, 0x00, 0x36, 0x00, 0x60, 0x00, 0x36, 0x00, 0xE0, 0x00, 0x3C, 0x00, 0xC0, 0x00, 0x1C, 0x00, 0xC0, 0x01, 0x1C, 0x00, 0x80, 0x07, 0x3F, 0x00, 0x00, 0xFF, 0x77, 0x00, 0x00, 0xFC, 0x61, // 81
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0xFF, 0x3F, 0x00, 0xE0, 0xFF, 0x3F, 0x00, 0x60, 0x30, 0x00, 0x00, 0x60, 0x30, 0x00, 0x00, 0x60, 0x30, 0x00, 0x00, 0x60, 0x30, 0x00, 0x00, 0x60, 0x70, 0x00, 0x00, 0x60, 0xF0, 0x00, 0x00, 0x60, 0xF0, 0x03, 0x00, 0x60, 0xB0, 0x07, 0x00, 0xE0, 0x18, 0x1F, 0x00, 0xC0, 0x1F, 0x3C, 0x00, 0x80, 0x0F, 0x30, 0x00, 0x00, 0x00, 0x20, // 82
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x07, 0x0F, 0x00, 0xC0, 0x1F, 0x1C, 0x00, 0xC0, 0x18, 0x18, 0x00, 0x60, 0x38, 0x38, 0x00, 0x60, 0x30, 0x30, 0x00, 0x60, 0x30, 0x30, 0x00, 0x60, 0x30, 0x30, 0x00, 0x60, 0x30, 0x30, 0x00, 0x60, 0x70, 0x30, 0x00, 0xC0, 0x60, 0x18, 0x00, 0xC0, 0xE1, 0x18, 0x00, 0x80, 0xC3, 0x0F, 0x00, 0x00, 0x83, 0x07, // 83
-0x60, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0xE0, 0xFF, 0x3F, 0x00, 0xE0, 0xFF, 0x3F, 0x00, 0x60, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x60, // 84
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0xFF, 0x03, 0x00, 0xE0, 0xFF, 0x0F, 0x00, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x1C, 0x00, 0xE0, 0xFF, 0x0F, 0x00, 0xE0, 0xFF, 0x03, // 85
-0x20, 0x00, 0x00, 0x00, 0xE0, 0x01, 0x00, 0x00, 0xC0, 0x0F, 0x00, 0x00, 0x00, 0x3E, 0x00, 0x00, 0x00, 0xF8, 0x01, 0x00, 0x00, 0xC0, 0x0F, 0x00, 0x00, 0x00, 0x3E, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x3E, 0x00, 0x00, 0xC0, 0x0F, 0x00, 0x00, 0xF8, 0x01, 0x00, 0x00, 0x3E, 0x00, 0x00, 0xC0, 0x0F, 0x00, 0x00, 0xE0, 0x01, 0x00, 0x00, 0x20, // 86
-0x60, 0x00, 0x00, 0x00, 0xE0, 0x07, 0x00, 0x00, 0x80, 0xFF, 0x00, 0x00, 0x00, 0xF8, 0x0F, 0x00, 0x00, 0x80, 0x3F, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x3F, 0x00, 0x00, 0xE0, 0x0F, 0x00, 0x00, 0xFC, 0x01, 0x00, 0x80, 0x1F, 0x00, 0x00, 0xE0, 0x03, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0xE0, 0x03, 0x00, 0x00, 0x80, 0x1F, 0x00, 0x00, 0x00, 0xFC, 0x01, 0x00, 0x00, 0xE0, 0x0F, 0x00, 0x00, 0x00, 0x3F, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x80, 0x3F, 0x00, 0x00, 0xF8, 0x0F, 0x00, 0x80, 0xFF, 0x00, 0x00, 0xE0, 0x07, 0x00, 0x00, 0x60, // 87
-0x00, 0x00, 0x20, 0x00, 0x20, 0x00, 0x30, 0x00, 0x60, 0x00, 0x3C, 0x00, 0xE0, 0x01, 0x1E, 0x00, 0xC0, 0x83, 0x07, 0x00, 0x00, 0xCF, 0x03, 0x00, 0x00, 0xFE, 0x01, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0xFE, 0x01, 0x00, 0x00, 0xCF, 0x03, 0x00, 0xC0, 0x03, 0x07, 0x00, 0xE0, 0x01, 0x1E, 0x00, 0x60, 0x00, 0x3C, 0x00, 0x20, 0x00, 0x30, 0x00, 0x00, 0x00, 0x20, // 88
-0x20, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0xC0, 0x01, 0x00, 0x00, 0x80, 0x03, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x1E, 0x00, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x00, 0xF0, 0x3F, 0x00, 0x00, 0xF0, 0x3F, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x00, 0x1E, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0xE0, 0x01, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x20, // 89
-0x00, 0x00, 0x30, 0x00, 0x60, 0x00, 0x38, 0x00, 0x60, 0x00, 0x3C, 0x00, 0x60, 0x00, 0x37, 0x00, 0x60, 0x80, 0x33, 0x00, 0x60, 0xC0, 0x31, 0x00, 0x60, 0xE0, 0x30, 0x00, 0x60, 0x38, 0x30, 0x00, 0x60, 0x1C, 0x30, 0x00, 0x60, 0x0E, 0x30, 0x00, 0x60, 0x07, 0x30, 0x00, 0xE0, 0x01, 0x30, 0x00, 0xE0, 0x00, 0x30, 0x00, 0x60, 0x00, 0x30, // 90
-0x00, 0x00, 0x00, 0x00, 0xE0, 0xFF, 0xFF, 0x07, 0xE0, 0xFF, 0xFF, 0x07, 0x60, 0x00, 0x00, 0x06, 0x60, 0x00, 0x00, 0x06, // 91
-0x60, 0x00, 0x00, 0x00, 0xE0, 0x03, 0x00, 0x00, 0x80, 0x3F, 0x00, 0x00, 0x00, 0xFC, 0x01, 0x00, 0x00, 0xE0, 0x0F, 0x00, 0x00, 0x00, 0x3E, 0x00, 0x00, 0x00, 0x30, // 92
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x06, 0x60, 0x00, 0x00, 0x06, 0xE0, 0xFF, 0xFF, 0x07, 0xE0, 0xFF, 0xFF, 0x07, // 93
-0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x1F, 0x00, 0x00, 0xC0, 0x07, 0x00, 0x00, 0xE0, 0x00, 0x00, 0x00, 0xE0, 0x00, 0x00, 0x00, 0xC0, 0x07, 0x00, 0x00, 0x00, 0x1F, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x20, // 94
-0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x06, // 95
-0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0xE0, 0x00, 0x00, 0x00, 0x80, // 96
-0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x0E, 0x00, 0x00, 0x1C, 0x1F, 0x00, 0x00, 0x8C, 0x39, 0x00, 0x00, 0x86, 0x31, 0x00, 0x00, 0x86, 0x31, 0x00, 0x00, 0xC6, 0x30, 0x00, 0x00, 0xC6, 0x18, 0x00, 0x00, 0xCE, 0x0C, 0x00, 0x00, 0xFC, 0x1F, 0x00, 0x00, 0xF8, 0x3F, 0x00, 0x00, 0x00, 0x20, // 97
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0xFF, 0x3F, 0x00, 0xE0, 0xFF, 0x3F, 0x00, 0x00, 0x18, 0x0C, 0x00, 0x00, 0x0C, 0x18, 0x00, 0x00, 0x06, 0x30, 0x00, 0x00, 0x06, 0x30, 0x00, 0x00, 0x06, 0x30, 0x00, 0x00, 0x0E, 0x38, 0x00, 0x00, 0x1C, 0x1C, 0x00, 0x00, 0xF8, 0x0F, 0x00, 0x00, 0xE0, 0x03, // 98
-0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x07, 0x00, 0x00, 0xF8, 0x0F, 0x00, 0x00, 0x1C, 0x1C, 0x00, 0x00, 0x0E, 0x38, 0x00, 0x00, 0x06, 0x30, 0x00, 0x00, 0x06, 0x30, 0x00, 0x00, 0x06, 0x30, 0x00, 0x00, 0x0E, 0x38, 0x00, 0x00, 0x1C, 0x1C, 0x00, 0x00, 0x18, 0x0C, // 99
-0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0x03, 0x00, 0x00, 0xF8, 0x0F, 0x00, 0x00, 0x1C, 0x1C, 0x00, 0x00, 0x0E, 0x38, 0x00, 0x00, 0x06, 0x30, 0x00, 0x00, 0x06, 0x30, 0x00, 0x00, 0x06, 0x30, 0x00, 0x00, 0x0C, 0x18, 0x00, 0x00, 0x18, 0x0C, 0x00, 0xE0, 0xFF, 0x3F, 0x00, 0xE0, 0xFF, 0x3F, // 100
-0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0x07, 0x00, 0x00, 0xF8, 0x0F, 0x00, 0x00, 0xDC, 0x1C, 0x00, 0x00, 0xCE, 0x38, 0x00, 0x00, 0xC6, 0x30, 0x00, 0x00, 0xC6, 0x30, 0x00, 0x00, 0xC6, 0x30, 0x00, 0x00, 0xCE, 0x38, 0x00, 0x00, 0xDC, 0x18, 0x00, 0x00, 0xF8, 0x0C, 0x00, 0x00, 0xF0, 0x04, // 101
-0x00, 0x06, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0xC0, 0xFF, 0x3F, 0x00, 0xE0, 0xFF, 0x3F, 0x00, 0x60, 0x06, 0x00, 0x00, 0x60, 0x06, 0x00, 0x00, 0x60, 0x06, // 102
-0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0x83, 0x01, 0x00, 0xF8, 0x8F, 0x03, 0x00, 0x1C, 0x1C, 0x07, 0x00, 0x0E, 0x38, 0x06, 0x00, 0x06, 0x30, 0x06, 0x00, 0x06, 0x30, 0x06, 0x00, 0x06, 0x30, 0x06, 0x00, 0x0C, 0x18, 0x07, 0x00, 0x18, 0x8C, 0x03, 0x00, 0xFE, 0xFF, 0x01, 0x00, 0xFE, 0xFF, // 103
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0xFF, 0x3F, 0x00, 0xE0, 0xFF, 0x3F, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0xFC, 0x3F, 0x00, 0x00, 0xF8, 0x3F, // 104
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0xFE, 0x3F, 0x00, 0x60, 0xFE, 0x3F, // 105
-0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x06, 0x60, 0xFE, 0xFF, 0x07, 0x60, 0xFE, 0xFF, 0x03, // 106
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0xFF, 0x3F, 0x00, 0xE0, 0xFF, 0x3F, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0xE0, 0x00, 0x00, 0x00, 0xF0, 0x01, 0x00, 0x00, 0x98, 0x07, 0x00, 0x00, 0x0C, 0x0E, 0x00, 0x00, 0x06, 0x3C, 0x00, 0x00, 0x02, 0x30, 0x00, 0x00, 0x00, 0x20, // 107
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0xFF, 0x3F, 0x00, 0xE0, 0xFF, 0x3F, // 108
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0x3F, 0x00, 0x00, 0xFE, 0x3F, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0xFC, 0x3F, 0x00, 0x00, 0xF8, 0x3F, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0xFC, 0x3F, 0x00, 0x00, 0xF8, 0x3F, // 109
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0x3F, 0x00, 0x00, 0xFE, 0x3F, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0xFC, 0x3F, 0x00, 0x00, 0xF8, 0x3F, // 110
-0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x07, 0x00, 0x00, 0xF8, 0x0F, 0x00, 0x00, 0x1C, 0x1C, 0x00, 0x00, 0x0E, 0x38, 0x00, 0x00, 0x06, 0x30, 0x00, 0x00, 0x06, 0x30, 0x00, 0x00, 0x06, 0x30, 0x00, 0x00, 0x0E, 0x38, 0x00, 0x00, 0x1C, 0x1C, 0x00, 0x00, 0xF8, 0x0F, 0x00, 0x00, 0xF0, 0x07, // 111
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0xFF, 0x07, 0x00, 0xFE, 0xFF, 0x07, 0x00, 0x18, 0x0C, 0x00, 0x00, 0x0C, 0x18, 0x00, 0x00, 0x06, 0x30, 0x00, 0x00, 0x06, 0x30, 0x00, 0x00, 0x06, 0x30, 0x00, 0x00, 0x0E, 0x38, 0x00, 0x00, 0x1C, 0x1C, 0x00, 0x00, 0xF8, 0x0F, 0x00, 0x00, 0xE0, 0x03, // 112
-0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0x03, 0x00, 0x00, 0xF8, 0x0F, 0x00, 0x00, 0x1C, 0x1C, 0x00, 0x00, 0x0E, 0x38, 0x00, 0x00, 0x06, 0x30, 0x00, 0x00, 0x06, 0x30, 0x00, 0x00, 0x06, 0x30, 0x00, 0x00, 0x0C, 0x18, 0x00, 0x00, 0x18, 0x0C, 0x00, 0x00, 0xFE, 0xFF, 0x07, 0x00, 0xFE, 0xFF, 0x07, // 113
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0x3F, 0x00, 0x00, 0xFE, 0x3F, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x06, // 114
-0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x0C, 0x00, 0x00, 0x7C, 0x1C, 0x00, 0x00, 0xEE, 0x38, 0x00, 0x00, 0xC6, 0x30, 0x00, 0x00, 0xC6, 0x30, 0x00, 0x00, 0xC6, 0x31, 0x00, 0x00, 0xC6, 0x31, 0x00, 0x00, 0x8E, 0x39, 0x00, 0x00, 0x9C, 0x1F, 0x00, 0x00, 0x18, 0x0F, // 115
-0x00, 0x06, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0xC0, 0xFF, 0x1F, 0x00, 0xE0, 0xFF, 0x3F, 0x00, 0x00, 0x06, 0x30, 0x00, 0x00, 0x06, 0x30, 0x00, 0x00, 0x06, 0x30, // 116
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0x0F, 0x00, 0x00, 0xFE, 0x1F, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0xFE, 0x3F, 0x00, 0x00, 0xFE, 0x3F, // 117
-0x00, 0x06, 0x00, 0x00, 0x00, 0x3E, 0x00, 0x00, 0x00, 0xF8, 0x00, 0x00, 0x00, 0xC0, 0x07, 0x00, 0x00, 0x00, 0x1F, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x1F, 0x00, 0x00, 0xC0, 0x07, 0x00, 0x00, 0xF8, 0x00, 0x00, 0x00, 0x3E, 0x00, 0x00, 0x00, 0x06, // 118
-0x00, 0x0E, 0x00, 0x00, 0x00, 0x7E, 0x00, 0x00, 0x00, 0xF0, 0x03, 0x00, 0x00, 0x80, 0x1F, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x80, 0x1F, 0x00, 0x00, 0xE0, 0x03, 0x00, 0x00, 0x7C, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x7C, 0x00, 0x00, 0x00, 0xE0, 0x03, 0x00, 0x00, 0x80, 0x1F, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x80, 0x1F, 0x00, 0x00, 0xF0, 0x03, 0x00, 0x00, 0x7E, 0x00, 0x00, 0x00, 0x0E, // 119
-0x00, 0x02, 0x20, 0x00, 0x00, 0x06, 0x30, 0x00, 0x00, 0x1E, 0x3C, 0x00, 0x00, 0x38, 0x0E, 0x00, 0x00, 0xF0, 0x07, 0x00, 0x00, 0xC0, 0x01, 0x00, 0x00, 0xE0, 0x07, 0x00, 0x00, 0x38, 0x0E, 0x00, 0x00, 0x1C, 0x3C, 0x00, 0x00, 0x0E, 0x30, 0x00, 0x00, 0x02, 0x20, // 120
-0x00, 0x00, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x7E, 0x00, 0x06, 0x00, 0xF0, 0x01, 0x06, 0x00, 0x80, 0x0F, 0x07, 0x00, 0x00, 0xFE, 0x03, 0x00, 0x00, 0xFC, 0x00, 0x00, 0xC0, 0x1F, 0x00, 0x00, 0xF8, 0x03, 0x00, 0x00, 0x3E, 0x00, 0x00, 0x00, 0x06, // 121
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x06, 0x3C, 0x00, 0x00, 0x06, 0x3E, 0x00, 0x00, 0x06, 0x37, 0x00, 0x00, 0xC6, 0x33, 0x00, 0x00, 0xE6, 0x30, 0x00, 0x00, 0x76, 0x30, 0x00, 0x00, 0x3E, 0x30, 0x00, 0x00, 0x1E, 0x30, 0x00, 0x00, 0x06, 0x30, // 122
-0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0xC0, 0x03, 0x00, 0xC0, 0x7F, 0xFE, 0x03, 0xE0, 0x3F, 0xFC, 0x07, 0x60, 0x00, 0x00, 0x06, 0x60, 0x00, 0x00, 0x06, // 123
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0xFF, 0xFF, 0x0F, 0xE0, 0xFF, 0xFF, 0x0F, // 124
-0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x06, 0x60, 0x00, 0x00, 0x06, 0xE0, 0x3F, 0xFC, 0x07, 0xC0, 0x7F, 0xFF, 0x03, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x80, 0x01, // 125
-0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0xE0, 0x00, 0x00, 0x00, 0x60, // 126
-0x00, 0x60, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0xE0, 0xFF, 0x3F, 0x00, 0xE0, 0xFF, 0x3F, 0x00, 0x00, 0x0C, 0x30, 0x00, 0x00, 0x06, 0x30, 0x00, 0x00, 0x03, 0x30, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x30, // 129
-0x00, 0x60, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0xE0, 0xFF, 0x3F, 0x00, 0xE0, 0xFF, 0x3F, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x06, // 130
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0xFF, 0x3F, 0x00, 0xE0, 0xFF, 0x3F, 0x00, 0xC0, 0x01, 0x00, 0x00, 0x80, 0x03, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x10, 0x3C, 0x00, 0x00, 0x1C, 0x70, 0x00, 0x00, 0x0C, 0xE0, 0x01, 0x00, 0x04, 0x80, 0x03, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x1C, 0x00, 0xE0, 0xFF, 0x3F, 0x00, 0xE0, 0xFF, 0x3F, // 131
-0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x3E, 0x00, 0x00, 0x80, 0x0F, 0x00, 0x00, 0xF0, 0x03, 0x00, 0x00, 0xFE, 0x01, 0x00, 0x80, 0x8F, 0x01, 0x00, 0xE0, 0x83, 0x01, 0x00, 0x60, 0x80, 0x01, 0x00, 0xE0, 0x83, 0x01, 0x00, 0x80, 0x8F, 0x01, 0x00, 0x00, 0xFE, 0x01, 0x00, 0x00, 0xF0, 0x03, 0x00, 0x00, 0x80, 0x0F, 0x00, 0x00, 0x00, 0xFE, 0x01, 0x00, 0x00, 0xB0, 0x03, 0x00, 0x00, 0x00, 0x03, // 132
-0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x0E, 0x00, 0x00, 0x1C, 0x1F, 0x00, 0x00, 0x8C, 0x39, 0x00, 0x00, 0x86, 0x31, 0x00, 0x00, 0x86, 0x31, 0x00, 0x00, 0xC6, 0x30, 0x00, 0x00, 0xC6, 0x18, 0x00, 0x00, 0xCE, 0x0C, 0x00, 0x00, 0xFC, 0x1F, 0x00, 0x00, 0xF8, 0xFF, 0x01, 0x00, 0x00, 0xA0, 0x03, 0x00, 0x00, 0x00, 0x03, // 133
-0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 0x01, 0x00, 0x00, 0xFF, 0x07, 0x00, 0x80, 0x07, 0x0F, 0x00, 0xC0, 0x01, 0x1C, 0x00, 0xC0, 0x00, 0x18, 0x00, 0x60, 0x00, 0x30, 0x00, 0x60, 0x00, 0x30, 0x00, 0x68, 0x00, 0x30, 0x00, 0x6E, 0x00, 0x30, 0x00, 0x66, 0x00, 0x30, 0x00, 0x62, 0x00, 0x30, 0x00, 0xC0, 0x00, 0x18, 0x00, 0xC0, 0x01, 0x1C, 0x00, 0x80, 0x03, 0x0F, 0x00, 0x00, 0x02, 0x03, // 134
-0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x07, 0x00, 0x00, 0xF8, 0x0F, 0x00, 0x00, 0x1C, 0x1C, 0x00, 0x00, 0x0E, 0x38, 0x00, 0x80, 0x06, 0x30, 0x00, 0xE0, 0x06, 0x30, 0x00, 0x60, 0x06, 0x30, 0x00, 0x20, 0x0E, 0x38, 0x00, 0x00, 0x1C, 0x1C, 0x00, 0x00, 0x18, 0x0C, // 135
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0x3F, 0x00, 0x00, 0xFE, 0x3F, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x80, 0x06, 0x00, 0x00, 0xE0, 0x06, 0x00, 0x00, 0x60, 0x06, 0x00, 0x00, 0x20, 0x0E, 0x00, 0x00, 0x00, 0xFC, 0x3F, 0x00, 0x00, 0xF8, 0x3F, // 136
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x06, 0x3C, 0x00, 0x00, 0x06, 0x3E, 0x00, 0x00, 0x06, 0x37, 0x00, 0x80, 0xC6, 0x33, 0x00, 0xE0, 0xE6, 0x30, 0x00, 0x60, 0x76, 0x30, 0x00, 0x20, 0x3E, 0x30, 0x00, 0x00, 0x1E, 0x30, 0x00, 0x00, 0x06, 0x30, // 137
-0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 0x01, 0x00, 0x00, 0xFF, 0x07, 0x00, 0x80, 0x07, 0x0F, 0x00, 0xC0, 0x01, 0x1C, 0x00, 0xC0, 0x00, 0x18, 0x00, 0xE0, 0x00, 0x38, 0x00, 0x60, 0x00, 0x30, 0x00, 0x60, 0x00, 0x30, 0x00, 0x68, 0x00, 0x30, 0x00, 0x6E, 0x00, 0x30, 0x00, 0x66, 0x00, 0x30, 0x00, 0xE2, 0x00, 0x38, 0x00, 0xC0, 0x00, 0x18, 0x00, 0xC0, 0x01, 0x1C, 0x00, 0x80, 0x07, 0x0F, 0x00, 0x00, 0xFF, 0x07, 0x00, 0x00, 0xFC, 0x01, // 147
-0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x07, 0x00, 0x00, 0xF8, 0x0F, 0x00, 0x00, 0x1C, 0x1C, 0x00, 0x00, 0x0E, 0x38, 0x00, 0x00, 0x06, 0x30, 0x00, 0x80, 0x06, 0x30, 0x00, 0xE0, 0x06, 0x30, 0x00, 0x60, 0x0E, 0x38, 0x00, 0x20, 0x1C, 0x1C, 0x00, 0x00, 0xF8, 0x0F, 0x00, 0x00, 0xF0, 0x07, // 148
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0xFF, 0x3F, 0x00, 0xE0, 0xFF, 0x3F, 0x00, 0x60, 0x30, 0x30, 0x00, 0x60, 0x30, 0x30, 0x00, 0x60, 0x30, 0x30, 0x00, 0x60, 0x30, 0x30, 0x00, 0x60, 0x30, 0xF0, 0x01, 0x60, 0x30, 0xB0, 0x03, 0x60, 0x30, 0x30, 0x03, 0x60, 0x30, 0x30, 0x00, 0x60, 0x30, 0x30, 0x00, 0x60, 0x30, 0x30, 0x00, 0x60, 0x00, 0x30, // 152
-0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0x07, 0x00, 0x00, 0xF8, 0x0F, 0x00, 0x00, 0xDC, 0x1C, 0x00, 0x00, 0xCE, 0x38, 0x00, 0x00, 0xC6, 0x30, 0x00, 0x00, 0xC6, 0xF0, 0x01, 0x00, 0xC6, 0xB0, 0x03, 0x00, 0xCE, 0x38, 0x03, 0x00, 0xDC, 0x18, 0x00, 0x00, 0xF8, 0x0C, 0x00, 0x00, 0xF0, 0x04, // 153
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x07, 0x0F, 0x00, 0xC0, 0x1F, 0x1C, 0x00, 0xC0, 0x18, 0x18, 0x00, 0x60, 0x38, 0x38, 0x00, 0x60, 0x30, 0x30, 0x00, 0x68, 0x30, 0x30, 0x00, 0x6E, 0x30, 0x30, 0x00, 0x66, 0x30, 0x30, 0x00, 0x62, 0x70, 0x30, 0x00, 0xC0, 0x60, 0x18, 0x00, 0xC0, 0xE1, 0x18, 0x00, 0x80, 0xC3, 0x0F, 0x00, 0x00, 0x83, 0x07, // 154
-0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x0C, 0x00, 0x00, 0x7C, 0x1C, 0x00, 0x00, 0xEE, 0x38, 0x00, 0x00, 0xC6, 0x30, 0x00, 0x80, 0xC6, 0x30, 0x00, 0xE0, 0xC6, 0x31, 0x00, 0x60, 0xC6, 0x31, 0x00, 0x20, 0x8E, 0x39, 0x00, 0x00, 0x9C, 0x1F, 0x00, 0x00, 0x18, 0x0F, // 155
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE6, 0xFF, 0x07, 0x00, 0xE6, 0xFF, 0x07, // 161
-0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0x07, 0x00, 0x00, 0xF8, 0x0F, 0x00, 0x00, 0x1C, 0x9C, 0x07, 0x00, 0x0E, 0x78, 0x00, 0x00, 0x06, 0x3F, 0x00, 0x00, 0xF6, 0x30, 0x00, 0x00, 0x0E, 0x30, 0x00, 0xE0, 0x0D, 0x1C, 0x00, 0x00, 0x1C, 0x0E, 0x00, 0x00, 0x10, 0x06, // 162
-0x00, 0x60, 0x10, 0x00, 0x00, 0x60, 0x38, 0x00, 0x00, 0x7F, 0x1C, 0x00, 0xC0, 0xFF, 0x1F, 0x00, 0xE0, 0xE0, 0x19, 0x00, 0x60, 0x60, 0x18, 0x00, 0x60, 0x60, 0x18, 0x00, 0x60, 0x60, 0x30, 0x00, 0xE0, 0x00, 0x30, 0x00, 0xC0, 0x01, 0x30, 0x00, 0x80, 0x01, 0x38, 0x00, 0x00, 0x00, 0x10, // 163
-0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x04, 0x00, 0x00, 0xF7, 0x0E, 0x00, 0x00, 0xFE, 0x07, 0x00, 0x00, 0x0C, 0x03, 0x00, 0x00, 0x06, 0x06, 0x00, 0x00, 0x06, 0x06, 0x00, 0x00, 0x06, 0x06, 0x00, 0x00, 0x06, 0x06, 0x00, 0x00, 0x0C, 0x03, 0x00, 0x00, 0xFE, 0x07, 0x00, 0x00, 0xF7, 0x0E, 0x00, 0x00, 0x02, 0x04, // 164
-0xE0, 0x60, 0x06, 0x00, 0xC0, 0x61, 0x06, 0x00, 0x80, 0x67, 0x06, 0x00, 0x00, 0x7E, 0x06, 0x00, 0x00, 0x7C, 0x06, 0x00, 0x00, 0xF0, 0x3F, 0x00, 0x00, 0xF0, 0x3F, 0x00, 0x00, 0x7C, 0x06, 0x00, 0x00, 0x7E, 0x06, 0x00, 0x80, 0x67, 0x06, 0x00, 0xC0, 0x61, 0x06, 0x00, 0xE0, 0x60, 0x06, 0x00, 0x20, // 165
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0x7F, 0xF8, 0x0F, 0xE0, 0x7F, 0xF8, 0x0F, // 166
-0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0x00, 0x00, 0x80, 0xF3, 0xC1, 0x00, 0xC0, 0x1F, 0xC3, 0x03, 0xE0, 0x0C, 0x07, 0x03, 0x60, 0x1C, 0x06, 0x06, 0x60, 0x18, 0x0C, 0x06, 0x60, 0x30, 0x1C, 0x06, 0xE0, 0x70, 0x38, 0x07, 0xC0, 0xE1, 0xF4, 0x03, 0x80, 0xC1, 0xE7, 0x01, 0x00, 0x80, 0x03, // 167
-0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x60, // 168
-0x00, 0xF8, 0x00, 0x00, 0x00, 0xFE, 0x03, 0x00, 0x00, 0x07, 0x07, 0x00, 0x80, 0x01, 0x0C, 0x00, 0xC0, 0x79, 0x1C, 0x00, 0xC0, 0xFE, 0x19, 0x00, 0x60, 0x86, 0x31, 0x00, 0x60, 0x03, 0x33, 0x00, 0x60, 0x03, 0x33, 0x00, 0x60, 0x03, 0x33, 0x00, 0x60, 0x03, 0x33, 0x00, 0x60, 0x87, 0x33, 0x00, 0xC0, 0x86, 0x19, 0x00, 0xC0, 0x85, 0x1C, 0x00, 0x80, 0x01, 0x0C, 0x00, 0x00, 0x07, 0x07, 0x00, 0x00, 0xFE, 0x03, 0x00, 0x00, 0xF8, // 169
-0x00, 0x00, 0x00, 0x00, 0xC0, 0x1C, 0x00, 0x00, 0xE0, 0x3E, 0x00, 0x00, 0x60, 0x32, 0x00, 0x00, 0x60, 0x32, 0x00, 0x00, 0xE0, 0x3F, 0x00, 0x00, 0xC0, 0x3F, // 170
-0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0xE0, 0x03, 0x00, 0x00, 0x78, 0x0F, 0x00, 0x00, 0x1C, 0x1C, 0x00, 0x00, 0x84, 0x10, 0x00, 0x00, 0xE0, 0x03, 0x00, 0x00, 0x78, 0x0F, 0x00, 0x00, 0x1C, 0x1C, 0x00, 0x00, 0x04, 0x10, // 171
-0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0xFC, 0x01, 0x00, 0x00, 0xFC, 0x01, // 172
-0x00, 0x80, 0x01, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x80, 0x01, // 173
-0x00, 0xF8, 0x00, 0x00, 0x00, 0xFE, 0x03, 0x00, 0x00, 0x07, 0x07, 0x00, 0x80, 0x01, 0x0C, 0x00, 0xC0, 0x01, 0x1C, 0x00, 0xC0, 0xFE, 0x1B, 0x00, 0x60, 0xFE, 0x33, 0x00, 0x60, 0x66, 0x30, 0x00, 0x60, 0x66, 0x30, 0x00, 0x60, 0xE6, 0x30, 0x00, 0x60, 0xFE, 0x31, 0x00, 0x60, 0x3C, 0x33, 0x00, 0xC0, 0x00, 0x1A, 0x00, 0xC0, 0x01, 0x1C, 0x00, 0x80, 0x01, 0x0C, 0x00, 0x00, 0x07, 0x07, 0x00, 0x00, 0xFE, 0x03, 0x00, 0x00, 0xF8, // 174
-0x0C, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x0C, // 175
-0x00, 0x00, 0x00, 0x00, 0x80, 0x03, 0x00, 0x00, 0x40, 0x04, 0x00, 0x00, 0x20, 0x08, 0x00, 0x00, 0x20, 0x08, 0x00, 0x00, 0x20, 0x08, 0x00, 0x00, 0x40, 0x04, 0x00, 0x00, 0x80, 0x03, // 176
-0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x30, 0x00, 0x00, 0x60, 0x30, 0x00, 0x00, 0x60, 0x30, 0x00, 0x00, 0x60, 0x30, 0x00, 0x00, 0x60, 0x30, 0x00, 0x00, 0xFF, 0x3F, 0x00, 0x00, 0xFF, 0x3F, 0x00, 0x00, 0x60, 0x30, 0x00, 0x00, 0x60, 0x30, 0x00, 0x00, 0x60, 0x30, 0x00, 0x00, 0x60, 0x30, 0x00, 0x00, 0x60, 0x30, // 177
-0x40, 0x20, 0x00, 0x00, 0x60, 0x30, 0x00, 0x00, 0x20, 0x38, 0x00, 0x00, 0x20, 0x2C, 0x00, 0x00, 0x20, 0x26, 0x00, 0x00, 0xE0, 0x23, 0x00, 0x00, 0xC0, 0x21, // 178
-0x40, 0x10, 0x00, 0x00, 0x60, 0x30, 0x00, 0x00, 0x20, 0x20, 0x00, 0x00, 0x20, 0x22, 0x00, 0x00, 0x20, 0x22, 0x00, 0x00, 0xE0, 0x3D, 0x00, 0x00, 0xC0, 0x1D, // 179
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0xE0, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x20, // 180
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0xFF, 0x07, 0x00, 0xFE, 0xFF, 0x07, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x1C, 0x00, 0x00, 0xFE, 0x3F, 0x00, 0x00, 0xFE, 0x3F, // 181
-0x00, 0x0F, 0x00, 0x00, 0xC0, 0x3F, 0x00, 0x00, 0xC0, 0x3F, 0x00, 0x00, 0xE0, 0x7F, 0x00, 0x00, 0xE0, 0x7F, 0x00, 0x00, 0xE0, 0xFF, 0xFF, 0x07, 0xE0, 0xFF, 0xFF, 0x07, 0x60, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0xE0, 0xFF, 0xFF, 0x07, 0xE0, 0xFF, 0xFF, 0x07, 0x60, 0x00, 0x00, 0x00, 0x60, // 182
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x60, // 183
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0xC0, 0x02, 0x00, 0x00, 0x80, 0x03, 0x00, 0x00, 0x00, 0x01, // 184
-0x00, 0x00, 0x30, 0x00, 0x60, 0x00, 0x38, 0x00, 0x60, 0x00, 0x3C, 0x00, 0x60, 0x00, 0x37, 0x00, 0x60, 0x80, 0x33, 0x00, 0x60, 0xC0, 0x31, 0x00, 0x68, 0xE0, 0x30, 0x00, 0x6E, 0x38, 0x30, 0x00, 0x66, 0x1C, 0x30, 0x00, 0x62, 0x0E, 0x30, 0x00, 0x60, 0x07, 0x30, 0x00, 0xE0, 0x01, 0x30, 0x00, 0xE0, 0x00, 0x30, 0x00, 0x60, 0x00, 0x30, // 185
-0x00, 0x00, 0x00, 0x00, 0x80, 0x0F, 0x00, 0x00, 0xC0, 0x1F, 0x00, 0x00, 0xE0, 0x38, 0x00, 0x00, 0x60, 0x30, 0x00, 0x00, 0xE0, 0x38, 0x00, 0x00, 0xC0, 0x1F, 0x00, 0x00, 0x80, 0x0F, // 186
-0x00, 0x00, 0x30, 0x00, 0x60, 0x00, 0x38, 0x00, 0x60, 0x00, 0x3C, 0x00, 0x60, 0x00, 0x37, 0x00, 0x60, 0x80, 0x33, 0x00, 0x60, 0xC0, 0x31, 0x00, 0x6C, 0xE0, 0x30, 0x00, 0x6C, 0x38, 0x30, 0x00, 0x60, 0x1C, 0x30, 0x00, 0x60, 0x0E, 0x30, 0x00, 0x60, 0x07, 0x30, 0x00, 0xE0, 0x01, 0x30, 0x00, 0xE0, 0x00, 0x30, 0x00, 0x60, 0x00, 0x30, // 187
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x06, 0x3C, 0x00, 0x00, 0x06, 0x3E, 0x00, 0x00, 0x06, 0x37, 0x00, 0xC0, 0xC6, 0x33, 0x00, 0xC0, 0xE6, 0x30, 0x00, 0x00, 0x76, 0x30, 0x00, 0x00, 0x3E, 0x30, 0x00, 0x00, 0x1E, 0x30, 0x00, 0x00, 0x06, 0x30, // 188
-0x00, 0x00, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x20, 0x00, 0xE0, 0x3F, 0x30, 0x00, 0xE0, 0x3F, 0x1C, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0xC0, 0x01, 0x00, 0x00, 0xE0, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x00, 0x4E, 0x20, 0x00, 0x00, 0x67, 0x30, 0x00, 0xC0, 0x21, 0x38, 0x00, 0xE0, 0x20, 0x2C, 0x00, 0x60, 0x20, 0x26, 0x00, 0x00, 0xE0, 0x27, 0x00, 0x00, 0xC0, 0x21, // 189
-0x40, 0x10, 0x00, 0x00, 0x60, 0x30, 0x00, 0x00, 0x20, 0x20, 0x00, 0x00, 0x20, 0x22, 0x20, 0x00, 0x20, 0x22, 0x30, 0x00, 0xE0, 0x3D, 0x38, 0x00, 0xC0, 0x1D, 0x0E, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x80, 0x03, 0x00, 0x00, 0xE0, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x0E, 0x0C, 0x00, 0x00, 0x07, 0x0E, 0x00, 0x80, 0x83, 0x0B, 0x00, 0xE0, 0xC0, 0x08, 0x00, 0x60, 0xE0, 0x3F, 0x00, 0x20, 0xE0, 0x3F, 0x00, 0x00, 0x00, 0x08, // 190
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x00, 0x00, 0x00, 0xF8, 0x03, 0x00, 0x00, 0x1E, 0x03, 0x00, 0x00, 0x07, 0x07, 0x00, 0xE6, 0x03, 0x06, 0x00, 0xE6, 0x01, 0x06, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x80, 0x03, 0x00, 0x00, 0xC0, 0x01, 0x00, 0x00, 0xC0, // 191
-0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x3E, 0x00, 0x00, 0x80, 0x0F, 0x00, 0x00, 0xF0, 0x03, 0x00, 0x00, 0xFE, 0x01, 0x00, 0x82, 0x8F, 0x01, 0x00, 0xE6, 0x83, 0x01, 0x00, 0x6E, 0x80, 0x01, 0x00, 0xE8, 0x83, 0x01, 0x00, 0x80, 0x8F, 0x01, 0x00, 0x00, 0xFE, 0x01, 0x00, 0x00, 0xF0, 0x03, 0x00, 0x00, 0x80, 0x0F, 0x00, 0x00, 0x00, 0x3E, 0x00, 0x00, 0x00, 0x30, // 192
-0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x3E, 0x00, 0x00, 0x80, 0x0F, 0x00, 0x00, 0xF0, 0x03, 0x00, 0x00, 0xFE, 0x01, 0x00, 0x80, 0x8F, 0x01, 0x00, 0xE8, 0x83, 0x01, 0x00, 0x6E, 0x80, 0x01, 0x00, 0xE6, 0x83, 0x01, 0x00, 0x82, 0x8F, 0x01, 0x00, 0x00, 0xFE, 0x01, 0x00, 0x00, 0xF0, 0x03, 0x00, 0x00, 0x80, 0x0F, 0x00, 0x00, 0x00, 0x3E, 0x00, 0x00, 0x00, 0x30, // 193
-0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x3E, 0x00, 0x00, 0x80, 0x0F, 0x00, 0x00, 0xF0, 0x03, 0x00, 0x00, 0xFE, 0x01, 0x00, 0x88, 0x8F, 0x01, 0x00, 0xEC, 0x83, 0x01, 0x00, 0x66, 0x80, 0x01, 0x00, 0xE6, 0x83, 0x01, 0x00, 0x8C, 0x8F, 0x01, 0x00, 0x08, 0xFE, 0x01, 0x00, 0x00, 0xF0, 0x03, 0x00, 0x00, 0x80, 0x0F, 0x00, 0x00, 0x00, 0x3E, 0x00, 0x00, 0x00, 0x30, // 194
-0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x3E, 0x00, 0x00, 0x80, 0x0F, 0x00, 0x00, 0xF0, 0x03, 0x00, 0x0C, 0xFE, 0x01, 0x00, 0x8E, 0x8F, 0x01, 0x00, 0xE6, 0x83, 0x01, 0x00, 0x66, 0x80, 0x01, 0x00, 0xEC, 0x83, 0x01, 0x00, 0x8C, 0x8F, 0x01, 0x00, 0x0E, 0xFE, 0x01, 0x00, 0x06, 0xF0, 0x03, 0x00, 0x00, 0x80, 0x0F, 0x00, 0x00, 0x00, 0x3E, 0x00, 0x00, 0x00, 0x30, // 195
-0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x3E, 0x00, 0x00, 0x80, 0x0F, 0x00, 0x00, 0xF0, 0x03, 0x00, 0x00, 0xFE, 0x01, 0x00, 0x8C, 0x8F, 0x01, 0x00, 0xEC, 0x83, 0x01, 0x00, 0x60, 0x80, 0x01, 0x00, 0xE0, 0x83, 0x01, 0x00, 0x8C, 0x8F, 0x01, 0x00, 0x0C, 0xFE, 0x01, 0x00, 0x00, 0xF0, 0x03, 0x00, 0x00, 0x80, 0x0F, 0x00, 0x00, 0x00, 0x3E, 0x00, 0x00, 0x00, 0x30, // 196
-0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x3E, 0x00, 0x00, 0x80, 0x0F, 0x00, 0x00, 0xF0, 0x03, 0x00, 0x00, 0xFE, 0x01, 0x00, 0x9C, 0x8F, 0x01, 0x00, 0xE2, 0x83, 0x01, 0x00, 0x62, 0x80, 0x01, 0x00, 0xE2, 0x83, 0x01, 0x00, 0x9C, 0x8F, 0x01, 0x00, 0x00, 0xFE, 0x01, 0x00, 0x00, 0xF0, 0x03, 0x00, 0x00, 0x80, 0x0F, 0x00, 0x00, 0x00, 0x3E, 0x00, 0x00, 0x00, 0x30, // 197
-0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0xF0, 0x01, 0x00, 0x00, 0xBC, 0x01, 0x00, 0x00, 0x8F, 0x01, 0x00, 0xC0, 0x83, 0x01, 0x00, 0xE0, 0x80, 0x01, 0x00, 0x60, 0x80, 0x01, 0x00, 0x60, 0x80, 0x01, 0x00, 0xE0, 0xFF, 0x3F, 0x00, 0xE0, 0xFF, 0x3F, 0x00, 0x60, 0x30, 0x30, 0x00, 0x60, 0x30, 0x30, 0x00, 0x60, 0x30, 0x30, 0x00, 0x60, 0x30, 0x30, 0x00, 0x60, 0x30, 0x30, 0x00, 0x60, 0x30, 0x30, 0x00, 0x60, 0x30, 0x30, 0x00, 0x60, 0x30, 0x30, 0x00, 0x60, 0x30, 0x30, 0x00, 0x60, 0x00, 0x30, // 198
-0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 0x01, 0x00, 0x00, 0xFF, 0x07, 0x00, 0x80, 0x07, 0x0F, 0x00, 0xC0, 0x01, 0x1C, 0x00, 0xC0, 0x00, 0x18, 0x00, 0x60, 0x00, 0x30, 0x02, 0x60, 0x00, 0x30, 0x02, 0x60, 0x00, 0xF0, 0x02, 0x60, 0x00, 0xB0, 0x03, 0x60, 0x00, 0x30, 0x01, 0x60, 0x00, 0x30, 0x00, 0xC0, 0x00, 0x18, 0x00, 0xC0, 0x01, 0x1C, 0x00, 0x80, 0x03, 0x0F, 0x00, 0x00, 0x02, 0x03, // 199
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0xFF, 0x3F, 0x00, 0xE0, 0xFF, 0x3F, 0x00, 0x60, 0x30, 0x30, 0x00, 0x60, 0x30, 0x30, 0x00, 0x62, 0x30, 0x30, 0x00, 0x66, 0x30, 0x30, 0x00, 0x6E, 0x30, 0x30, 0x00, 0x68, 0x30, 0x30, 0x00, 0x60, 0x30, 0x30, 0x00, 0x60, 0x30, 0x30, 0x00, 0x60, 0x30, 0x30, 0x00, 0x60, 0x30, 0x30, 0x00, 0x60, 0x00, 0x30, // 200
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0xFF, 0x3F, 0x00, 0xE0, 0xFF, 0x3F, 0x00, 0x60, 0x30, 0x30, 0x00, 0x60, 0x30, 0x30, 0x00, 0x60, 0x30, 0x30, 0x00, 0x68, 0x30, 0x30, 0x00, 0x6E, 0x30, 0x30, 0x00, 0x66, 0x30, 0x30, 0x00, 0x62, 0x30, 0x30, 0x00, 0x60, 0x30, 0x30, 0x00, 0x60, 0x30, 0x30, 0x00, 0x60, 0x30, 0x30, 0x00, 0x60, 0x00, 0x30, // 201
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0xFF, 0x3F, 0x00, 0xE0, 0xFF, 0x3F, 0x00, 0x60, 0x30, 0x30, 0x00, 0x60, 0x30, 0x30, 0x00, 0x68, 0x30, 0x30, 0x00, 0x6C, 0x30, 0x30, 0x00, 0x66, 0x30, 0x30, 0x00, 0x66, 0x30, 0x30, 0x00, 0x6C, 0x30, 0x30, 0x00, 0x68, 0x30, 0x30, 0x00, 0x60, 0x30, 0x30, 0x00, 0x60, 0x30, 0x30, 0x00, 0x60, 0x00, 0x30, // 202
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0xFF, 0x3F, 0x00, 0xE0, 0xFF, 0x3F, 0x00, 0x60, 0x30, 0x30, 0x00, 0x60, 0x30, 0x30, 0x00, 0x6C, 0x30, 0x30, 0x00, 0x6C, 0x30, 0x30, 0x00, 0x60, 0x30, 0x30, 0x00, 0x60, 0x30, 0x30, 0x00, 0x6C, 0x30, 0x30, 0x00, 0x6C, 0x30, 0x30, 0x00, 0x60, 0x30, 0x30, 0x00, 0x60, 0x30, 0x30, 0x00, 0x60, 0x00, 0x30, // 203
-0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0xE6, 0xFF, 0x3F, 0x00, 0xEE, 0xFF, 0x3F, 0x00, 0x08, // 204
-0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0xEE, 0xFF, 0x3F, 0x00, 0xE6, 0xFF, 0x3F, 0x00, 0x02, // 205
-0x08, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0xE6, 0xFF, 0x3F, 0x00, 0xE6, 0xFF, 0x3F, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x08, // 206
-0x0C, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0xE0, 0xFF, 0x3F, 0x00, 0xE0, 0xFF, 0x3F, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x0C, // 207
-0x00, 0x30, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0xE0, 0xFF, 0x3F, 0x00, 0xE0, 0xFF, 0x3F, 0x00, 0x60, 0x30, 0x30, 0x00, 0x60, 0x30, 0x30, 0x00, 0x60, 0x30, 0x30, 0x00, 0x60, 0x30, 0x30, 0x00, 0x60, 0x30, 0x30, 0x00, 0x60, 0x00, 0x30, 0x00, 0x60, 0x00, 0x30, 0x00, 0xE0, 0x00, 0x18, 0x00, 0xC0, 0x01, 0x1C, 0x00, 0x80, 0x03, 0x0E, 0x00, 0x00, 0xFF, 0x07, 0x00, 0x00, 0xFC, 0x01, // 208
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0xFF, 0x3F, 0x00, 0xE0, 0xFF, 0x3F, 0x00, 0xC0, 0x01, 0x00, 0x00, 0x8C, 0x03, 0x00, 0x00, 0x0E, 0x0E, 0x00, 0x00, 0x06, 0x3C, 0x00, 0x00, 0x06, 0x70, 0x00, 0x00, 0x0C, 0xE0, 0x01, 0x00, 0x0C, 0x80, 0x03, 0x00, 0x0E, 0x00, 0x0F, 0x00, 0x06, 0x00, 0x1C, 0x00, 0xE0, 0xFF, 0x3F, 0x00, 0xE0, 0xFF, 0x3F, // 209
-0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 0x01, 0x00, 0x00, 0xFF, 0x07, 0x00, 0x80, 0x07, 0x0F, 0x00, 0xC0, 0x01, 0x1C, 0x00, 0xC0, 0x00, 0x18, 0x00, 0xE0, 0x00, 0x38, 0x00, 0x62, 0x00, 0x30, 0x00, 0x66, 0x00, 0x30, 0x00, 0x6E, 0x00, 0x30, 0x00, 0x68, 0x00, 0x30, 0x00, 0x60, 0x00, 0x30, 0x00, 0xE0, 0x00, 0x38, 0x00, 0xC0, 0x00, 0x18, 0x00, 0xC0, 0x01, 0x1C, 0x00, 0x80, 0x07, 0x0F, 0x00, 0x00, 0xFF, 0x07, 0x00, 0x00, 0xFC, 0x01, // 210
-0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 0x01, 0x00, 0x00, 0xFF, 0x07, 0x00, 0x80, 0x07, 0x0F, 0x00, 0xC0, 0x01, 0x1C, 0x00, 0xC0, 0x00, 0x18, 0x00, 0xE0, 0x00, 0x38, 0x00, 0x60, 0x00, 0x30, 0x00, 0x68, 0x00, 0x30, 0x00, 0x6E, 0x00, 0x30, 0x00, 0x66, 0x00, 0x30, 0x00, 0x62, 0x00, 0x30, 0x00, 0xE0, 0x00, 0x38, 0x00, 0xC0, 0x00, 0x18, 0x00, 0xC0, 0x01, 0x1C, 0x00, 0x80, 0x07, 0x0F, 0x00, 0x00, 0xFF, 0x07, 0x00, 0x00, 0xFC, 0x01, // 211
-0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 0x01, 0x00, 0x00, 0xFF, 0x07, 0x00, 0x80, 0x07, 0x0F, 0x00, 0xC0, 0x01, 0x1C, 0x00, 0xC0, 0x00, 0x18, 0x00, 0xE0, 0x00, 0x38, 0x00, 0x68, 0x00, 0x30, 0x00, 0x6C, 0x00, 0x30, 0x00, 0x66, 0x00, 0x30, 0x00, 0x66, 0x00, 0x30, 0x00, 0x6C, 0x00, 0x30, 0x00, 0xE8, 0x00, 0x38, 0x00, 0xC0, 0x00, 0x18, 0x00, 0xC0, 0x01, 0x1C, 0x00, 0x80, 0x07, 0x0F, 0x00, 0x00, 0xFF, 0x07, 0x00, 0x00, 0xFC, 0x01, // 212
-0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 0x01, 0x00, 0x00, 0xFF, 0x07, 0x00, 0x80, 0x07, 0x0F, 0x00, 0xC0, 0x01, 0x1C, 0x00, 0xCC, 0x00, 0x18, 0x00, 0xEE, 0x00, 0x38, 0x00, 0x66, 0x00, 0x30, 0x00, 0x66, 0x00, 0x30, 0x00, 0x6C, 0x00, 0x30, 0x00, 0x6C, 0x00, 0x30, 0x00, 0x6E, 0x00, 0x30, 0x00, 0xE6, 0x00, 0x38, 0x00, 0xC0, 0x00, 0x18, 0x00, 0xC0, 0x01, 0x1C, 0x00, 0x80, 0x07, 0x0F, 0x00, 0x00, 0xFF, 0x07, 0x00, 0x00, 0xFC, 0x01, // 213
-0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 0x01, 0x00, 0x00, 0xFF, 0x07, 0x00, 0x80, 0x07, 0x0F, 0x00, 0xC0, 0x01, 0x1C, 0x00, 0xC0, 0x00, 0x18, 0x00, 0xE0, 0x00, 0x38, 0x00, 0x6C, 0x00, 0x30, 0x00, 0x6C, 0x00, 0x30, 0x00, 0x60, 0x00, 0x30, 0x00, 0x60, 0x00, 0x30, 0x00, 0x6C, 0x00, 0x30, 0x00, 0xEC, 0x00, 0x38, 0x00, 0xC0, 0x00, 0x18, 0x00, 0xC0, 0x01, 0x1C, 0x00, 0x80, 0x07, 0x0F, 0x00, 0x00, 0xFF, 0x07, 0x00, 0x00, 0xFC, 0x01, // 214
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x03, 0x00, 0x00, 0x8E, 0x03, 0x00, 0x00, 0xDC, 0x01, 0x00, 0x00, 0xF8, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0xF8, 0x00, 0x00, 0x00, 0xDC, 0x01, 0x00, 0x00, 0x8E, 0x03, 0x00, 0x00, 0x06, 0x03, // 215
-0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 0x21, 0x00, 0x00, 0xFF, 0x77, 0x00, 0x80, 0x07, 0x3F, 0x00, 0xC0, 0x01, 0x1E, 0x00, 0xC0, 0x00, 0x1F, 0x00, 0xE0, 0x80, 0x3B, 0x00, 0x60, 0xC0, 0x31, 0x00, 0x60, 0xE0, 0x30, 0x00, 0x60, 0x70, 0x30, 0x00, 0x60, 0x38, 0x30, 0x00, 0x60, 0x1C, 0x30, 0x00, 0xE0, 0x0E, 0x38, 0x00, 0xC0, 0x07, 0x18, 0x00, 0xC0, 0x03, 0x1C, 0x00, 0xE0, 0x07, 0x0F, 0x00, 0x70, 0xFF, 0x07, 0x00, 0x20, 0xFC, 0x01, // 216
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0xFF, 0x03, 0x00, 0xE0, 0xFF, 0x0F, 0x00, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x00, 0x38, 0x00, 0x02, 0x00, 0x30, 0x00, 0x06, 0x00, 0x30, 0x00, 0x0E, 0x00, 0x30, 0x00, 0x08, 0x00, 0x30, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x1C, 0x00, 0xE0, 0xFF, 0x0F, 0x00, 0xE0, 0xFF, 0x03, // 217
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0xFF, 0x03, 0x00, 0xE0, 0xFF, 0x0F, 0x00, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x30, 0x00, 0x08, 0x00, 0x30, 0x00, 0x0E, 0x00, 0x30, 0x00, 0x06, 0x00, 0x30, 0x00, 0x02, 0x00, 0x30, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x1C, 0x00, 0xE0, 0xFF, 0x0F, 0x00, 0xE0, 0xFF, 0x03, // 218
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0xFF, 0x03, 0x00, 0xE0, 0xFF, 0x0F, 0x00, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x00, 0x38, 0x00, 0x08, 0x00, 0x30, 0x00, 0x0C, 0x00, 0x30, 0x00, 0x06, 0x00, 0x30, 0x00, 0x06, 0x00, 0x30, 0x00, 0x0C, 0x00, 0x30, 0x00, 0x08, 0x00, 0x38, 0x00, 0x00, 0x00, 0x1C, 0x00, 0xE0, 0xFF, 0x0F, 0x00, 0xE0, 0xFF, 0x03, // 219
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0xFF, 0x03, 0x00, 0xE0, 0xFF, 0x0F, 0x00, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x00, 0x38, 0x00, 0x0C, 0x00, 0x30, 0x00, 0x0C, 0x00, 0x30, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x30, 0x00, 0x0C, 0x00, 0x30, 0x00, 0x0C, 0x00, 0x38, 0x00, 0x00, 0x00, 0x1C, 0x00, 0xE0, 0xFF, 0x0F, 0x00, 0xE0, 0xFF, 0x03, // 220
-0x20, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0xC0, 0x01, 0x00, 0x00, 0x80, 0x03, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x1E, 0x00, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x08, 0xF0, 0x3F, 0x00, 0x0E, 0xF0, 0x3F, 0x00, 0x06, 0x3C, 0x00, 0x00, 0x02, 0x1E, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0xE0, 0x01, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x20, // 221
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0xFF, 0x3F, 0x00, 0xE0, 0xFF, 0x3F, 0x00, 0x00, 0x03, 0x06, 0x00, 0x00, 0x03, 0x06, 0x00, 0x00, 0x03, 0x06, 0x00, 0x00, 0x03, 0x06, 0x00, 0x00, 0x03, 0x06, 0x00, 0x00, 0x03, 0x06, 0x00, 0x00, 0x03, 0x06, 0x00, 0x00, 0x03, 0x07, 0x00, 0x00, 0x86, 0x03, 0x00, 0x00, 0xFE, 0x01, 0x00, 0x00, 0xF8, // 222
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xFF, 0x3F, 0x00, 0xC0, 0xFF, 0x3F, 0x00, 0xC0, 0x00, 0x00, 0x00, 0x60, 0x00, 0x08, 0x00, 0x60, 0x00, 0x1C, 0x00, 0x60, 0x00, 0x38, 0x00, 0xE0, 0x78, 0x30, 0x00, 0xC0, 0x7F, 0x30, 0x00, 0x80, 0xC7, 0x30, 0x00, 0x00, 0x80, 0x39, 0x00, 0x00, 0x80, 0x1F, 0x00, 0x00, 0x00, 0x0F, // 223
-0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x0E, 0x00, 0x00, 0x1C, 0x1F, 0x00, 0x00, 0x8C, 0x39, 0x00, 0x20, 0x86, 0x31, 0x00, 0x60, 0x86, 0x31, 0x00, 0xE0, 0xC6, 0x30, 0x00, 0x80, 0xC6, 0x18, 0x00, 0x00, 0xCE, 0x0C, 0x00, 0x00, 0xFC, 0x1F, 0x00, 0x00, 0xF8, 0x3F, 0x00, 0x00, 0x00, 0x20, // 224
-0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x0E, 0x00, 0x00, 0x1C, 0x1F, 0x00, 0x00, 0x8C, 0x39, 0x00, 0x00, 0x86, 0x31, 0x00, 0x80, 0x86, 0x31, 0x00, 0xE0, 0xC6, 0x30, 0x00, 0x60, 0xC6, 0x18, 0x00, 0x20, 0xCE, 0x0C, 0x00, 0x00, 0xFC, 0x1F, 0x00, 0x00, 0xF8, 0x3F, 0x00, 0x00, 0x00, 0x20, // 225
-0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x0E, 0x00, 0x00, 0x1C, 0x1F, 0x00, 0x80, 0x8C, 0x39, 0x00, 0xC0, 0x86, 0x31, 0x00, 0x60, 0x86, 0x31, 0x00, 0x60, 0xC6, 0x30, 0x00, 0xC0, 0xC6, 0x18, 0x00, 0x80, 0xCE, 0x0C, 0x00, 0x00, 0xFC, 0x1F, 0x00, 0x00, 0xF8, 0x3F, 0x00, 0x00, 0x00, 0x20, // 226
-0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x0E, 0x00, 0xC0, 0x1C, 0x1F, 0x00, 0xE0, 0x8C, 0x39, 0x00, 0x60, 0x86, 0x31, 0x00, 0x60, 0x86, 0x31, 0x00, 0xC0, 0xC6, 0x30, 0x00, 0xC0, 0xC6, 0x18, 0x00, 0xE0, 0xCE, 0x0C, 0x00, 0x60, 0xFC, 0x1F, 0x00, 0x00, 0xF8, 0x3F, 0x00, 0x00, 0x00, 0x20, // 227
-0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x0E, 0x00, 0x00, 0x1C, 0x1F, 0x00, 0xC0, 0x8C, 0x39, 0x00, 0xC0, 0x86, 0x31, 0x00, 0x00, 0x86, 0x31, 0x00, 0x00, 0xC6, 0x30, 0x00, 0xC0, 0xC6, 0x18, 0x00, 0xC0, 0xCE, 0x0C, 0x00, 0x00, 0xFC, 0x1F, 0x00, 0x00, 0xF8, 0x3F, 0x00, 0x00, 0x00, 0x20, // 228
-0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x0E, 0x00, 0x00, 0x1C, 0x1F, 0x00, 0x00, 0x8C, 0x39, 0x00, 0x70, 0x86, 0x31, 0x00, 0x88, 0x86, 0x31, 0x00, 0x88, 0xC6, 0x30, 0x00, 0x88, 0xC6, 0x18, 0x00, 0x70, 0xCE, 0x0C, 0x00, 0x00, 0xFC, 0x1F, 0x00, 0x00, 0xF8, 0x3F, 0x00, 0x00, 0x00, 0x20, // 229
-0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x0F, 0x00, 0x00, 0x9C, 0x1F, 0x00, 0x00, 0xCC, 0x39, 0x00, 0x00, 0xC6, 0x30, 0x00, 0x00, 0xC6, 0x30, 0x00, 0x00, 0xC6, 0x30, 0x00, 0x00, 0xC6, 0x30, 0x00, 0x00, 0x66, 0x18, 0x00, 0x00, 0x6E, 0x1C, 0x00, 0x00, 0xFC, 0x0F, 0x00, 0x00, 0xFC, 0x1F, 0x00, 0x00, 0xCC, 0x1C, 0x00, 0x00, 0xCE, 0x38, 0x00, 0x00, 0xC6, 0x30, 0x00, 0x00, 0xC6, 0x30, 0x00, 0x00, 0xC6, 0x30, 0x00, 0x00, 0xC6, 0x30, 0x00, 0x00, 0xCC, 0x18, 0x00, 0x00, 0xF8, 0x0C, 0x00, 0x00, 0xE0, 0x04, // 230
-0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x07, 0x00, 0x00, 0xF8, 0x0F, 0x00, 0x00, 0x1C, 0x1C, 0x00, 0x00, 0x0E, 0x38, 0x02, 0x00, 0x06, 0x30, 0x02, 0x00, 0x06, 0xF0, 0x02, 0x00, 0x06, 0xB0, 0x03, 0x00, 0x0E, 0x38, 0x01, 0x00, 0x1C, 0x1C, 0x00, 0x00, 0x18, 0x0C, // 231
-0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0x07, 0x00, 0x00, 0xF8, 0x0F, 0x00, 0x00, 0xDC, 0x1C, 0x00, 0x20, 0xCE, 0x38, 0x00, 0x60, 0xC6, 0x30, 0x00, 0xE0, 0xC6, 0x30, 0x00, 0x80, 0xC6, 0x30, 0x00, 0x00, 0xCE, 0x38, 0x00, 0x00, 0xDC, 0x18, 0x00, 0x00, 0xF8, 0x0C, 0x00, 0x00, 0xF0, 0x04, // 232
-0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0x07, 0x00, 0x00, 0xF8, 0x0F, 0x00, 0x00, 0xDC, 0x1C, 0x00, 0x00, 0xCE, 0x38, 0x00, 0x80, 0xC6, 0x30, 0x00, 0xE0, 0xC6, 0x30, 0x00, 0x60, 0xC6, 0x30, 0x00, 0x20, 0xCE, 0x38, 0x00, 0x00, 0xDC, 0x18, 0x00, 0x00, 0xF8, 0x0C, 0x00, 0x00, 0xF0, 0x04, // 233
-0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0x07, 0x00, 0x00, 0xF8, 0x0F, 0x00, 0x00, 0xDC, 0x1C, 0x00, 0x80, 0xCE, 0x38, 0x00, 0xC0, 0xC6, 0x30, 0x00, 0x60, 0xC6, 0x30, 0x00, 0x60, 0xC6, 0x30, 0x00, 0xC0, 0xCE, 0x38, 0x00, 0x80, 0xDC, 0x18, 0x00, 0x00, 0xF8, 0x0C, 0x00, 0x00, 0xF0, 0x04, // 234
-0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0x07, 0x00, 0x00, 0xF8, 0x0F, 0x00, 0x00, 0xDC, 0x1C, 0x00, 0xC0, 0xCE, 0x38, 0x00, 0xC0, 0xC6, 0x30, 0x00, 0x00, 0xC6, 0x30, 0x00, 0x00, 0xC6, 0x30, 0x00, 0xC0, 0xCE, 0x38, 0x00, 0xC0, 0xDC, 0x18, 0x00, 0x00, 0xF8, 0x0C, 0x00, 0x00, 0xF0, 0x04, // 235
-0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x60, 0xFE, 0x3F, 0x00, 0xE0, 0xFE, 0x3F, 0x00, 0x80, // 236
-0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0xE0, 0xFE, 0x3F, 0x00, 0x60, 0xFE, 0x3F, 0x00, 0x20, // 237
-0x80, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0x60, 0xFE, 0x3F, 0x00, 0x60, 0xFE, 0x3F, 0x00, 0xC0, 0x00, 0x00, 0x00, 0x80, // 238
-0xC0, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0x00, 0xFE, 0x3F, 0x00, 0x00, 0xFE, 0x3F, 0x00, 0xC0, 0x00, 0x00, 0x00, 0xC0, // 239
-0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x07, 0x00, 0x00, 0xF8, 0x0F, 0x00, 0x00, 0x1D, 0x1C, 0x00, 0xA0, 0x0F, 0x38, 0x00, 0xA0, 0x06, 0x30, 0x00, 0xE0, 0x06, 0x30, 0x00, 0xC0, 0x06, 0x30, 0x00, 0xC0, 0x0F, 0x38, 0x00, 0x20, 0x1F, 0x1C, 0x00, 0x00, 0xFC, 0x0F, 0x00, 0x00, 0xE0, 0x07, // 240
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0x3F, 0x00, 0xC0, 0xFE, 0x3F, 0x00, 0xE0, 0x18, 0x00, 0x00, 0x60, 0x0C, 0x00, 0x00, 0x60, 0x06, 0x00, 0x00, 0xC0, 0x06, 0x00, 0x00, 0xC0, 0x06, 0x00, 0x00, 0xE0, 0x0E, 0x00, 0x00, 0x60, 0xFC, 0x3F, 0x00, 0x00, 0xF8, 0x3F, // 241
-0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x07, 0x00, 0x00, 0xF8, 0x0F, 0x00, 0x00, 0x1C, 0x1C, 0x00, 0x20, 0x0E, 0x38, 0x00, 0x60, 0x06, 0x30, 0x00, 0xE0, 0x06, 0x30, 0x00, 0x80, 0x06, 0x30, 0x00, 0x00, 0x0E, 0x38, 0x00, 0x00, 0x1C, 0x1C, 0x00, 0x00, 0xF8, 0x0F, 0x00, 0x00, 0xF0, 0x07, // 242
-0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x07, 0x00, 0x00, 0xF8, 0x0F, 0x00, 0x00, 0x1C, 0x1C, 0x00, 0x00, 0x0E, 0x38, 0x00, 0x80, 0x06, 0x30, 0x00, 0xE0, 0x06, 0x30, 0x00, 0x60, 0x06, 0x30, 0x00, 0x20, 0x0E, 0x38, 0x00, 0x00, 0x1C, 0x1C, 0x00, 0x00, 0xF8, 0x0F, 0x00, 0x00, 0xF0, 0x07, // 243
-0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x07, 0x00, 0x00, 0xF8, 0x0F, 0x00, 0x00, 0x1C, 0x1C, 0x00, 0x80, 0x0E, 0x38, 0x00, 0xC0, 0x06, 0x30, 0x00, 0x60, 0x06, 0x30, 0x00, 0x60, 0x06, 0x30, 0x00, 0xC0, 0x0E, 0x38, 0x00, 0x80, 0x1C, 0x1C, 0x00, 0x00, 0xF8, 0x0F, 0x00, 0x00, 0xF0, 0x07, // 244
-0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x07, 0x00, 0x00, 0xF8, 0x0F, 0x00, 0xC0, 0x1C, 0x1C, 0x00, 0xE0, 0x0E, 0x38, 0x00, 0x60, 0x06, 0x30, 0x00, 0x60, 0x06, 0x30, 0x00, 0xC0, 0x06, 0x30, 0x00, 0xC0, 0x0E, 0x38, 0x00, 0xE0, 0x1C, 0x1C, 0x00, 0x60, 0xF8, 0x0F, 0x00, 0x00, 0xF0, 0x07, // 245
-0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x07, 0x00, 0x00, 0xF8, 0x0F, 0x00, 0x00, 0x1C, 0x1C, 0x00, 0xC0, 0x0E, 0x38, 0x00, 0xC0, 0x06, 0x30, 0x00, 0x00, 0x06, 0x30, 0x00, 0x00, 0x06, 0x30, 0x00, 0xC0, 0x0E, 0x38, 0x00, 0xC0, 0x1C, 0x1C, 0x00, 0x00, 0xF8, 0x0F, 0x00, 0x00, 0xF0, 0x07, // 246
-0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0xB6, 0x01, 0x00, 0x00, 0xB6, 0x01, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x30, // 247
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x67, 0x00, 0x00, 0xF8, 0x7F, 0x00, 0x00, 0x1C, 0x1C, 0x00, 0x00, 0x0E, 0x3F, 0x00, 0x00, 0x86, 0x33, 0x00, 0x00, 0xE6, 0x31, 0x00, 0x00, 0x76, 0x30, 0x00, 0x00, 0x3E, 0x38, 0x00, 0x00, 0x1C, 0x1C, 0x00, 0x00, 0xFF, 0x0F, 0x00, 0x00, 0xF3, 0x07, // 248
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0x0F, 0x00, 0x00, 0xFE, 0x1F, 0x00, 0x20, 0x00, 0x38, 0x00, 0x60, 0x00, 0x30, 0x00, 0xE0, 0x00, 0x30, 0x00, 0x80, 0x00, 0x30, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0xFE, 0x3F, 0x00, 0x00, 0xFE, 0x3F, // 249
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0x0F, 0x00, 0x00, 0xFE, 0x1F, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x30, 0x00, 0x80, 0x00, 0x30, 0x00, 0xE0, 0x00, 0x30, 0x00, 0x60, 0x00, 0x18, 0x00, 0x20, 0x00, 0x0C, 0x00, 0x00, 0xFE, 0x3F, 0x00, 0x00, 0xFE, 0x3F, // 250
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0x0F, 0x00, 0x00, 0xFE, 0x1F, 0x00, 0x80, 0x00, 0x38, 0x00, 0xC0, 0x00, 0x30, 0x00, 0x60, 0x00, 0x30, 0x00, 0x60, 0x00, 0x30, 0x00, 0xC0, 0x00, 0x18, 0x00, 0x80, 0x00, 0x0C, 0x00, 0x00, 0xFE, 0x3F, 0x00, 0x00, 0xFE, 0x3F, // 251
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0x0F, 0x00, 0x00, 0xFE, 0x1F, 0x00, 0xC0, 0x00, 0x38, 0x00, 0xC0, 0x00, 0x30, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x30, 0x00, 0xC0, 0x00, 0x18, 0x00, 0xC0, 0x00, 0x0C, 0x00, 0x00, 0xFE, 0x3F, 0x00, 0x00, 0xFE, 0x3F, // 252
-0x00, 0x00, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x7E, 0x00, 0x06, 0x00, 0xF0, 0x01, 0x06, 0x00, 0x80, 0x0F, 0x07, 0x80, 0x00, 0xFE, 0x03, 0xE0, 0x00, 0xFC, 0x00, 0x60, 0xC0, 0x1F, 0x00, 0x20, 0xF8, 0x03, 0x00, 0x00, 0x3E, 0x00, 0x00, 0x00, 0x06, // 253
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0xFF, 0xFF, 0x07, 0xE0, 0xFF, 0xFF, 0x07, 0x00, 0x1C, 0x18, 0x00, 0x00, 0x06, 0x30, 0x00, 0x00, 0x06, 0x30, 0x00, 0x00, 0x06, 0x30, 0x00, 0x00, 0x0E, 0x38, 0x00, 0x00, 0x1C, 0x1C, 0x00, 0x00, 0xF8, 0x0F, 0x00, 0x00, 0xF0, 0x03, // 254
-0x00, 0x00, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x7E, 0x00, 0x06, 0xC0, 0xF0, 0x01, 0x06, 0xC0, 0x80, 0x0F, 0x07, 0x00, 0x00, 0xFE, 0x03, 0x00, 0x00, 0xFC, 0x00, 0xC0, 0xC0, 0x1F, 0x00, 0xC0, 0xF8, 0x03, 0x00, 0x00, 0x3E, 0x00, 0x00, 0x00, 0x06, // 255
+ 0x18, // Width: 24
+ 0x1C, // Height: 28
+ 0x20, // First char: 32
+ 0xE0, // Number of chars: 224
+ // Jump Table:
+ 0xFF, 0xFF, 0x00, 0x06, // 32
+ 0x00, 0x00, 0x13, 0x06, // 33
+ 0x00, 0x13, 0x1A, 0x08, // 34
+ 0x00, 0x2D, 0x33, 0x0E, // 35
+ 0x00, 0x60, 0x2F, 0x0D, // 36
+ 0x00, 0x8F, 0x4F, 0x15, // 37
+ 0x00, 0xDE, 0x3B, 0x10, // 38
+ 0x01, 0x19, 0x0A, 0x04, // 39
+ 0x01, 0x23, 0x1C, 0x08, // 40
+ 0x01, 0x3F, 0x1B, 0x08, // 41
+ 0x01, 0x5A, 0x21, 0x0A, // 42
+ 0x01, 0x7B, 0x32, 0x0E, // 43
+ 0x01, 0xAD, 0x10, 0x05, // 44
+ 0x01, 0xBD, 0x1B, 0x08, // 45
+ 0x01, 0xD8, 0x0F, 0x05, // 46
+ 0x01, 0xE7, 0x19, 0x08, // 47
+ 0x02, 0x00, 0x2F, 0x0D, // 48
+ 0x02, 0x2F, 0x23, 0x0A, // 49
+ 0x02, 0x52, 0x2F, 0x0D, // 50
+ 0x02, 0x81, 0x2F, 0x0D, // 51
+ 0x02, 0xB0, 0x2F, 0x0D, // 52
+ 0x02, 0xDF, 0x2F, 0x0D, // 53
+ 0x03, 0x0E, 0x2F, 0x0D, // 54
+ 0x03, 0x3D, 0x2D, 0x0D, // 55
+ 0x03, 0x6A, 0x2F, 0x0D, // 56
+ 0x03, 0x99, 0x2F, 0x0D, // 57
+ 0x03, 0xC8, 0x0F, 0x05, // 58
+ 0x03, 0xD7, 0x10, 0x05, // 59
+ 0x03, 0xE7, 0x2F, 0x0D, // 60
+ 0x04, 0x16, 0x2F, 0x0D, // 61
+ 0x04, 0x45, 0x2E, 0x0D, // 62
+ 0x04, 0x73, 0x2E, 0x0D, // 63
+ 0x04, 0xA1, 0x5B, 0x18, // 64
+ 0x04, 0xFC, 0x3B, 0x10, // 65
+ 0x05, 0x37, 0x3B, 0x10, // 66
+ 0x05, 0x72, 0x3F, 0x11, // 67
+ 0x05, 0xB1, 0x3F, 0x11, // 68
+ 0x05, 0xF0, 0x3B, 0x10, // 69
+ 0x06, 0x2B, 0x35, 0x0F, // 70
+ 0x06, 0x60, 0x43, 0x12, // 71
+ 0x06, 0xA3, 0x3B, 0x10, // 72
+ 0x06, 0xDE, 0x0F, 0x05, // 73
+ 0x06, 0xED, 0x27, 0x0B, // 74
+ 0x07, 0x14, 0x3F, 0x11, // 75
+ 0x07, 0x53, 0x2F, 0x0D, // 76
+ 0x07, 0x82, 0x43, 0x12, // 77
+ 0x07, 0xC5, 0x3B, 0x10, // 78
+ 0x08, 0x00, 0x47, 0x13, // 79
+ 0x08, 0x47, 0x3A, 0x10, // 80
+ 0x08, 0x81, 0x47, 0x13, // 81
+ 0x08, 0xC8, 0x3F, 0x11, // 82
+ 0x09, 0x07, 0x3B, 0x10, // 83
+ 0x09, 0x42, 0x35, 0x0F, // 84
+ 0x09, 0x77, 0x3B, 0x10, // 85
+ 0x09, 0xB2, 0x39, 0x10, // 86
+ 0x09, 0xEB, 0x59, 0x18, // 87
+ 0x0A, 0x44, 0x3B, 0x10, // 88
+ 0x0A, 0x7F, 0x3D, 0x11, // 89
+ 0x0A, 0xBC, 0x37, 0x0F, // 90
+ 0x0A, 0xF3, 0x14, 0x06, // 91
+ 0x0B, 0x07, 0x1B, 0x08, // 92
+ 0x0B, 0x22, 0x18, 0x07, // 93
+ 0x0B, 0x3A, 0x2A, 0x0C, // 94
+ 0x0B, 0x64, 0x34, 0x0E, // 95
+ 0x0B, 0x98, 0x11, 0x06, // 96
+ 0x0B, 0xA9, 0x2F, 0x0D, // 97
+ 0x0B, 0xD8, 0x33, 0x0E, // 98
+ 0x0C, 0x0B, 0x2B, 0x0C, // 99
+ 0x0C, 0x36, 0x2F, 0x0D, // 100
+ 0x0C, 0x65, 0x2F, 0x0D, // 101
+ 0x0C, 0x94, 0x1A, 0x08, // 102
+ 0x0C, 0xAE, 0x2F, 0x0D, // 103
+ 0x0C, 0xDD, 0x2F, 0x0D, // 104
+ 0x0D, 0x0C, 0x0F, 0x05, // 105
+ 0x0D, 0x1B, 0x10, 0x05, // 106
+ 0x0D, 0x2B, 0x2F, 0x0D, // 107
+ 0x0D, 0x5A, 0x0F, 0x05, // 108
+ 0x0D, 0x69, 0x47, 0x13, // 109
+ 0x0D, 0xB0, 0x2F, 0x0D, // 110
+ 0x0D, 0xDF, 0x2F, 0x0D, // 111
+ 0x0E, 0x0E, 0x33, 0x0E, // 112
+ 0x0E, 0x41, 0x30, 0x0D, // 113
+ 0x0E, 0x71, 0x1E, 0x09, // 114
+ 0x0E, 0x8F, 0x2B, 0x0C, // 115
+ 0x0E, 0xBA, 0x1B, 0x08, // 116
+ 0x0E, 0xD5, 0x2F, 0x0D, // 117
+ 0x0F, 0x04, 0x2A, 0x0C, // 118
+ 0x0F, 0x2E, 0x42, 0x12, // 119
+ 0x0F, 0x70, 0x2B, 0x0C, // 120
+ 0x0F, 0x9B, 0x2A, 0x0C, // 121
+ 0x0F, 0xC5, 0x2B, 0x0C, // 122
+ 0x0F, 0xF0, 0x1C, 0x08, // 123
+ 0x10, 0x0C, 0x10, 0x05, // 124
+ 0x10, 0x1C, 0x1B, 0x08, // 125
+ 0x10, 0x37, 0x32, 0x0E, // 126
+ 0xFF, 0xFF, 0x00, 0x18, // 127
+ 0xFF, 0xFF, 0x00, 0x18, // 128
+ 0x10, 0x69, 0x2F, 0x0D, // 129
+ 0x10, 0x98, 0x16, 0x07, // 130
+ 0x10, 0xAE, 0x3B, 0x10, // 131
+ 0x10, 0xE9, 0x40, 0x11, // 132
+ 0x11, 0x29, 0x34, 0x0E, // 133
+ 0x11, 0x5D, 0x3F, 0x11, // 134
+ 0x11, 0x9C, 0x2B, 0x0C, // 135
+ 0x11, 0xC7, 0x2F, 0x0D, // 136
+ 0x11, 0xF6, 0x2B, 0x0C, // 137
+ 0xFF, 0xFF, 0x00, 0x18, // 138
+ 0xFF, 0xFF, 0x00, 0x18, // 139
+ 0xFF, 0xFF, 0x00, 0x18, // 140
+ 0xFF, 0xFF, 0x00, 0x18, // 141
+ 0xFF, 0xFF, 0x00, 0x18, // 142
+ 0xFF, 0xFF, 0x00, 0x18, // 143
+ 0xFF, 0xFF, 0x00, 0x18, // 144
+ 0xFF, 0xFF, 0x00, 0x18, // 145
+ 0xFF, 0xFF, 0x00, 0x18, // 146
+ 0x12, 0x21, 0x47, 0x13, // 147
+ 0x12, 0x68, 0x2F, 0x0D, // 148
+ 0xFF, 0xFF, 0x00, 0x18, // 149
+ 0xFF, 0xFF, 0x00, 0x18, // 150
+ 0xFF, 0xFF, 0x00, 0x18, // 151
+ 0x12, 0x97, 0x3B, 0x10, // 152
+ 0x12, 0xD2, 0x2F, 0x0D, // 153
+ 0x13, 0x01, 0x3B, 0x10, // 154
+ 0x13, 0x3C, 0x2B, 0x0C, // 155
+ 0xFF, 0xFF, 0x00, 0x18, // 156
+ 0xFF, 0xFF, 0x00, 0x18, // 157
+ 0xFF, 0xFF, 0x00, 0x18, // 158
+ 0xFF, 0xFF, 0x00, 0x18, // 159
+ 0xFF, 0xFF, 0x00, 0x18, // 160
+ 0x13, 0x67, 0x14, 0x06, // 161
+ 0x13, 0x7B, 0x2B, 0x0C, // 162
+ 0x13, 0xA6, 0x2F, 0x0D, // 163
+ 0x13, 0xD5, 0x33, 0x0E, // 164
+ 0x14, 0x08, 0x31, 0x0E, // 165
+ 0x14, 0x39, 0x10, 0x05, // 166
+ 0x14, 0x49, 0x2F, 0x0D, // 167
+ 0x14, 0x78, 0x19, 0x08, // 168
+ 0x14, 0x91, 0x46, 0x13, // 169
+ 0x14, 0xD7, 0x1A, 0x08, // 170
+ 0x14, 0xF1, 0x27, 0x0B, // 171
+ 0x15, 0x18, 0x2F, 0x0D, // 172
+ 0x15, 0x47, 0x1B, 0x08, // 173
+ 0x15, 0x62, 0x46, 0x13, // 174
+ 0x15, 0xA8, 0x31, 0x0E, // 175
+ 0x15, 0xD9, 0x1E, 0x09, // 176
+ 0x15, 0xF7, 0x33, 0x0E, // 177
+ 0x16, 0x2A, 0x1A, 0x08, // 178
+ 0x16, 0x44, 0x1A, 0x08, // 179
+ 0x16, 0x5E, 0x19, 0x08, // 180
+ 0x16, 0x77, 0x2F, 0x0D, // 181
+ 0x16, 0xA6, 0x31, 0x0E, // 182
+ 0x16, 0xD7, 0x12, 0x06, // 183
+ 0x16, 0xE9, 0x18, 0x07, // 184
+ 0x17, 0x01, 0x37, 0x0F, // 185
+ 0x17, 0x38, 0x1E, 0x09, // 186
+ 0x17, 0x56, 0x37, 0x0F, // 187
+ 0x17, 0x8D, 0x2B, 0x0C, // 188
+ 0x17, 0xB8, 0x4B, 0x14, // 189
+ 0x18, 0x03, 0x4B, 0x14, // 190
+ 0x18, 0x4E, 0x33, 0x0E, // 191
+ 0x18, 0x81, 0x3B, 0x10, // 192
+ 0x18, 0xBC, 0x3B, 0x10, // 193
+ 0x18, 0xF7, 0x3B, 0x10, // 194
+ 0x19, 0x32, 0x3B, 0x10, // 195
+ 0x19, 0x6D, 0x3B, 0x10, // 196
+ 0x19, 0xA8, 0x3B, 0x10, // 197
+ 0x19, 0xE3, 0x5B, 0x18, // 198
+ 0x1A, 0x3E, 0x3F, 0x11, // 199
+ 0x1A, 0x7D, 0x3B, 0x10, // 200
+ 0x1A, 0xB8, 0x3B, 0x10, // 201
+ 0x1A, 0xF3, 0x3B, 0x10, // 202
+ 0x1B, 0x2E, 0x3B, 0x10, // 203
+ 0x1B, 0x69, 0x11, 0x06, // 204
+ 0x1B, 0x7A, 0x11, 0x06, // 205
+ 0x1B, 0x8B, 0x15, 0x07, // 206
+ 0x1B, 0xA0, 0x15, 0x07, // 207
+ 0x1B, 0xB5, 0x3F, 0x11, // 208
+ 0x1B, 0xF4, 0x3B, 0x10, // 209
+ 0x1C, 0x2F, 0x47, 0x13, // 210
+ 0x1C, 0x76, 0x47, 0x13, // 211
+ 0x1C, 0xBD, 0x47, 0x13, // 212
+ 0x1D, 0x04, 0x47, 0x13, // 213
+ 0x1D, 0x4B, 0x47, 0x13, // 214
+ 0x1D, 0x92, 0x2B, 0x0C, // 215
+ 0x1D, 0xBD, 0x47, 0x13, // 216
+ 0x1E, 0x04, 0x3B, 0x10, // 217
+ 0x1E, 0x3F, 0x3B, 0x10, // 218
+ 0x1E, 0x7A, 0x3B, 0x10, // 219
+ 0x1E, 0xB5, 0x3B, 0x10, // 220
+ 0x1E, 0xF0, 0x3D, 0x11, // 221
+ 0x1F, 0x2D, 0x3A, 0x10, // 222
+ 0x1F, 0x67, 0x37, 0x0F, // 223
+ 0x1F, 0x9E, 0x2F, 0x0D, // 224
+ 0x1F, 0xCD, 0x2F, 0x0D, // 225
+ 0x1F, 0xFC, 0x2F, 0x0D, // 226
+ 0x20, 0x2B, 0x2F, 0x0D, // 227
+ 0x20, 0x5A, 0x2F, 0x0D, // 228
+ 0x20, 0x89, 0x2F, 0x0D, // 229
+ 0x20, 0xB8, 0x53, 0x16, // 230
+ 0x21, 0x0B, 0x2B, 0x0C, // 231
+ 0x21, 0x36, 0x2F, 0x0D, // 232
+ 0x21, 0x65, 0x2F, 0x0D, // 233
+ 0x21, 0x94, 0x2F, 0x0D, // 234
+ 0x21, 0xC3, 0x2F, 0x0D, // 235
+ 0x21, 0xF2, 0x11, 0x06, // 236
+ 0x22, 0x03, 0x11, 0x06, // 237
+ 0x22, 0x14, 0x15, 0x07, // 238
+ 0x22, 0x29, 0x15, 0x07, // 239
+ 0x22, 0x3E, 0x2F, 0x0D, // 240
+ 0x22, 0x6D, 0x2F, 0x0D, // 241
+ 0x22, 0x9C, 0x2F, 0x0D, // 242
+ 0x22, 0xCB, 0x2F, 0x0D, // 243
+ 0x22, 0xFA, 0x2F, 0x0D, // 244
+ 0x23, 0x29, 0x2F, 0x0D, // 245
+ 0x23, 0x58, 0x2F, 0x0D, // 246
+ 0x23, 0x87, 0x32, 0x0E, // 247
+ 0x23, 0xB9, 0x33, 0x0E, // 248
+ 0x23, 0xEC, 0x2F, 0x0D, // 249
+ 0x24, 0x1B, 0x2F, 0x0D, // 250
+ 0x24, 0x4A, 0x2F, 0x0D, // 251
+ 0x24, 0x79, 0x2F, 0x0D, // 252
+ 0x24, 0xA8, 0x2A, 0x0C, // 253
+ 0x24, 0xD2, 0x2F, 0x0D, // 254
+ 0x25, 0x01, 0x2A, 0x0C, // 255
+ // Font Data:
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0xFF, 0x33, 0x00, 0xE0, 0xFF, 0x33, // 33
+ 0x00, 0x00, 0x00, 0x00, 0xE0, 0x07, 0x00, 0x00, 0xE0, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0x07, 0x00, 0x00, 0xE0, 0x07, // 34
+ 0x00, 0x0C, 0x03, 0x00, 0x00, 0x0C, 0x33, 0x00, 0x00, 0x0C, 0x3F, 0x00, 0x00, 0xFC, 0x0F, 0x00, 0x80, 0xFF, 0x03, 0x00, 0xE0, 0x0F, 0x03, 0x00, 0x60, 0x0C, 0x33, 0x00, 0x00, 0x0C, 0x3F, 0x00, 0x00, 0xFC, 0x0F, 0x00, 0x80, 0xFF, 0x03, 0x00, 0xE0, 0x0F, 0x03, 0x00, 0x60, 0x0C, 0x03, 0x00, 0x00, 0x0C, 0x03, // 35
+ 0x00, 0x00, 0x00, 0x00, 0x80, 0x07, 0x06, 0x00, 0xC0, 0x0F, 0x1E, 0x00, 0xC0, 0x18, 0x1C, 0x00, 0x60, 0x18, 0x38, 0x00, 0x60, 0x30, 0x30, 0x00, 0xF0, 0xFF, 0xFF, 0x00, 0x60, 0x30, 0x30, 0x00, 0x60, 0x60, 0x38, 0x00, 0xC0, 0x60, 0x18, 0x00, 0xC0, 0xC1, 0x1F, 0x00, 0x00, 0x81, 0x07, // 36
+ 0x00, 0x00, 0x00, 0x00, 0x80, 0x0F, 0x00, 0x00, 0xC0, 0x1F, 0x00, 0x00, 0x60, 0x30, 0x00, 0x00, 0x20, 0x20, 0x00, 0x00, 0x20, 0x20, 0x20, 0x00, 0x60, 0x30, 0x38, 0x00, 0xC0, 0x1F, 0x1E, 0x00, 0x80, 0x8F, 0x0F, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0xF0, 0x00, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x00, 0x8F, 0x0F, 0x00, 0xC0, 0xC3, 0x1F, 0x00, 0xE0, 0x60, 0x30, 0x00, 0x20, 0x20, 0x20, 0x00, 0x00, 0x20, 0x20, 0x00, 0x00, 0x60, 0x30, 0x00, 0x00, 0xC0, 0x1F, 0x00, 0x00, 0x80, 0x0F, // 37
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x07, 0x00, 0x00, 0xC0, 0x0F, 0x00, 0x80, 0xE3, 0x1C, 0x00, 0xC0, 0x77, 0x38, 0x00, 0xE0, 0x3C, 0x30, 0x00, 0x60, 0x38, 0x30, 0x00, 0x60, 0x78, 0x30, 0x00, 0xE0, 0xEC, 0x38, 0x00, 0xC0, 0x8F, 0x1B, 0x00, 0x80, 0x03, 0x1F, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0xC0, 0x1F, 0x00, 0x00, 0xC0, 0x38, 0x00, 0x00, 0x00, 0x10, // 38
+ 0x00, 0x00, 0x00, 0x00, 0xE0, 0x07, 0x00, 0x00, 0xE0, 0x07, // 39
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x0F, 0x00, 0x00, 0xFE, 0x7F, 0x00, 0x80, 0x0F, 0xF0, 0x01, 0xC0, 0x01, 0x80, 0x03, 0x60, 0x00, 0x00, 0x06, 0x20, 0x00, 0x00, 0x04, // 40
+ 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x04, 0x60, 0x00, 0x00, 0x06, 0xC0, 0x01, 0x80, 0x03, 0x80, 0x0F, 0xF0, 0x01, 0x00, 0xFE, 0x7F, 0x00, 0x00, 0xF0, 0x0F, // 41
+ 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x04, 0x00, 0x00, 0x80, 0x0F, 0x00, 0x00, 0xE0, 0x03, 0x00, 0x00, 0xE0, 0x03, 0x00, 0x00, 0x80, 0x0F, 0x00, 0x00, 0x80, 0x04, 0x00, 0x00, 0x80, // 42
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0xFF, 0x0F, 0x00, 0x00, 0xFF, 0x0F, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x60, // 43
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x03, 0x00, 0x00, 0xF0, 0x01, // 44
+ 0x00, 0x80, 0x01, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x80, 0x01, // 45
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x30, // 46
+ 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x3E, 0x00, 0x00, 0xE0, 0x0F, 0x00, 0x00, 0xFC, 0x01, 0x00, 0x80, 0x3F, 0x00, 0x00, 0xE0, 0x03, 0x00, 0x00, 0x60, // 47
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0x03, 0x00, 0x80, 0xFF, 0x0F, 0x00, 0xC0, 0x01, 0x1C, 0x00, 0xE0, 0x00, 0x38, 0x00, 0x60, 0x00, 0x30, 0x00, 0x60, 0x00, 0x30, 0x00, 0x60, 0x00, 0x30, 0x00, 0xE0, 0x00, 0x38, 0x00, 0xC0, 0x01, 0x1C, 0x00, 0x80, 0xFF, 0x0F, 0x00, 0x00, 0xFE, 0x03, // 48
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0xE0, 0xFF, 0x3F, 0x00, 0xE0, 0xFF, 0x3F, // 49
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x30, 0x00, 0xC0, 0x03, 0x38, 0x00, 0xC0, 0x00, 0x3C, 0x00, 0x60, 0x00, 0x36, 0x00, 0x60, 0x00, 0x33, 0x00, 0x60, 0x80, 0x31, 0x00, 0x60, 0xC0, 0x30, 0x00, 0x60, 0x60, 0x30, 0x00, 0xC0, 0x30, 0x30, 0x00, 0xC0, 0x1F, 0x30, 0x00, 0x00, 0x0F, 0x30, // 50
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x06, 0x00, 0xC0, 0x01, 0x0E, 0x00, 0xC0, 0x00, 0x1C, 0x00, 0x60, 0x00, 0x30, 0x00, 0x60, 0x30, 0x30, 0x00, 0x60, 0x30, 0x30, 0x00, 0x60, 0x30, 0x30, 0x00, 0xC0, 0x38, 0x30, 0x00, 0xC0, 0x6F, 0x18, 0x00, 0x80, 0xC7, 0x0F, 0x00, 0x00, 0x80, 0x07, // 51
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x03, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0xF0, 0x03, 0x00, 0x00, 0x3C, 0x03, 0x00, 0x00, 0x0E, 0x03, 0x00, 0x80, 0x07, 0x03, 0x00, 0xC0, 0x01, 0x03, 0x00, 0xE0, 0xFF, 0x3F, 0x00, 0xE0, 0xFF, 0x3F, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, // 52
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x06, 0x00, 0x80, 0x3F, 0x0E, 0x00, 0xE0, 0x1F, 0x18, 0x00, 0x60, 0x08, 0x30, 0x00, 0x60, 0x0C, 0x30, 0x00, 0x60, 0x0C, 0x30, 0x00, 0x60, 0x0C, 0x30, 0x00, 0x60, 0x0C, 0x30, 0x00, 0x60, 0x18, 0x1C, 0x00, 0x60, 0xF0, 0x0F, 0x00, 0x00, 0xE0, 0x03, // 53
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 0x03, 0x00, 0x80, 0xFF, 0x0F, 0x00, 0xC0, 0x63, 0x1C, 0x00, 0xC0, 0x30, 0x38, 0x00, 0x60, 0x18, 0x30, 0x00, 0x60, 0x18, 0x30, 0x00, 0x60, 0x18, 0x30, 0x00, 0x60, 0x18, 0x30, 0x00, 0xE0, 0x30, 0x18, 0x00, 0xC0, 0xF1, 0x0F, 0x00, 0x80, 0xC1, 0x07, // 54
+ 0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x60, 0x00, 0x3C, 0x00, 0x60, 0x80, 0x3F, 0x00, 0x60, 0xE0, 0x03, 0x00, 0x60, 0x78, 0x00, 0x00, 0x60, 0x0E, 0x00, 0x00, 0x60, 0x03, 0x00, 0x00, 0xE0, 0x01, 0x00, 0x00, 0x60, // 55
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x07, 0x00, 0x80, 0xC7, 0x1F, 0x00, 0xC0, 0x6F, 0x18, 0x00, 0xE0, 0x38, 0x30, 0x00, 0x60, 0x30, 0x30, 0x00, 0x60, 0x30, 0x30, 0x00, 0x60, 0x30, 0x30, 0x00, 0xE0, 0x38, 0x30, 0x00, 0xC0, 0x6F, 0x18, 0x00, 0x80, 0xC7, 0x1F, 0x00, 0x00, 0x80, 0x07, // 56
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x0C, 0x00, 0x80, 0x7F, 0x1C, 0x00, 0xC0, 0x61, 0x38, 0x00, 0x60, 0xC0, 0x30, 0x00, 0x60, 0xC0, 0x30, 0x00, 0x60, 0xC0, 0x30, 0x00, 0x60, 0xC0, 0x30, 0x00, 0x60, 0x60, 0x18, 0x00, 0xC0, 0x31, 0x1E, 0x00, 0x80, 0xFF, 0x0F, 0x00, 0x00, 0xFE, 0x01, // 57
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x30, 0x00, 0x00, 0x06, 0x30, // 58
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x30, 0x03, 0x00, 0x06, 0xF0, 0x01, // 59
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0xD8, 0x00, 0x00, 0x00, 0xD8, 0x00, 0x00, 0x00, 0x8C, 0x01, 0x00, 0x00, 0x8C, 0x01, 0x00, 0x00, 0x04, 0x01, 0x00, 0x00, 0x06, 0x03, 0x00, 0x00, 0x06, 0x03, 0x00, 0x00, 0x03, 0x06, // 60
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x8C, 0x01, 0x00, 0x00, 0x8C, 0x01, 0x00, 0x00, 0x8C, 0x01, 0x00, 0x00, 0x8C, 0x01, 0x00, 0x00, 0x8C, 0x01, 0x00, 0x00, 0x8C, 0x01, 0x00, 0x00, 0x8C, 0x01, 0x00, 0x00, 0x8C, 0x01, 0x00, 0x00, 0x8C, 0x01, 0x00, 0x00, 0x8C, 0x01, 0x00, 0x00, 0x8C, 0x01, // 61
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x06, 0x00, 0x00, 0x06, 0x03, 0x00, 0x00, 0x06, 0x03, 0x00, 0x00, 0x04, 0x01, 0x00, 0x00, 0x8C, 0x01, 0x00, 0x00, 0x8C, 0x01, 0x00, 0x00, 0xD8, 0x00, 0x00, 0x00, 0xD8, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x20, // 62
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x80, 0x03, 0x00, 0x00, 0xC0, 0x01, 0x00, 0x00, 0xE0, 0x00, 0x00, 0x00, 0x60, 0x80, 0x33, 0x00, 0x60, 0xC0, 0x33, 0x00, 0x60, 0xE0, 0x00, 0x00, 0x60, 0x30, 0x00, 0x00, 0xC0, 0x38, 0x00, 0x00, 0xC0, 0x1F, 0x00, 0x00, 0x00, 0x07, // 63
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0x0F, 0x00, 0x00, 0xF8, 0x3F, 0x00, 0x00, 0x1E, 0xF0, 0x00, 0x00, 0x07, 0xC0, 0x01, 0x80, 0xC3, 0x87, 0x01, 0xC0, 0xF1, 0x9F, 0x03, 0xC0, 0x38, 0x18, 0x03, 0xC0, 0x0C, 0x30, 0x03, 0x60, 0x0E, 0x30, 0x06, 0x60, 0x06, 0x30, 0x06, 0x60, 0x06, 0x18, 0x06, 0x60, 0x06, 0x0C, 0x06, 0x60, 0x0C, 0x1E, 0x06, 0x60, 0xF8, 0x3F, 0x06, 0xE0, 0xFE, 0x31, 0x06, 0xC0, 0x0E, 0x30, 0x06, 0xC0, 0x01, 0x18, 0x03, 0x80, 0x03, 0x1C, 0x03, 0x00, 0x07, 0x8F, 0x01, 0x00, 0xFE, 0x87, 0x01, 0x00, 0xF8, 0xC1, 0x00, 0x00, 0x00, 0x40, // 64
+ 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x3E, 0x00, 0x00, 0x80, 0x0F, 0x00, 0x00, 0xF0, 0x03, 0x00, 0x00, 0xFE, 0x01, 0x00, 0x80, 0x8F, 0x01, 0x00, 0xE0, 0x83, 0x01, 0x00, 0x60, 0x80, 0x01, 0x00, 0xE0, 0x83, 0x01, 0x00, 0x80, 0x8F, 0x01, 0x00, 0x00, 0xFE, 0x01, 0x00, 0x00, 0xF0, 0x03, 0x00, 0x00, 0x80, 0x0F, 0x00, 0x00, 0x00, 0x3E, 0x00, 0x00, 0x00, 0x30, // 65
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0xFF, 0x3F, 0x00, 0xE0, 0xFF, 0x3F, 0x00, 0x60, 0x30, 0x30, 0x00, 0x60, 0x30, 0x30, 0x00, 0x60, 0x30, 0x30, 0x00, 0x60, 0x30, 0x30, 0x00, 0x60, 0x30, 0x30, 0x00, 0x60, 0x30, 0x30, 0x00, 0x60, 0x30, 0x30, 0x00, 0xC0, 0x78, 0x30, 0x00, 0xC0, 0xFF, 0x18, 0x00, 0x80, 0xC7, 0x1F, 0x00, 0x00, 0x80, 0x07, // 66
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 0x01, 0x00, 0x00, 0xFF, 0x07, 0x00, 0x80, 0x07, 0x0F, 0x00, 0xC0, 0x01, 0x1C, 0x00, 0xC0, 0x00, 0x18, 0x00, 0x60, 0x00, 0x30, 0x00, 0x60, 0x00, 0x30, 0x00, 0x60, 0x00, 0x30, 0x00, 0x60, 0x00, 0x30, 0x00, 0x60, 0x00, 0x30, 0x00, 0x60, 0x00, 0x30, 0x00, 0xC0, 0x00, 0x18, 0x00, 0xC0, 0x01, 0x1C, 0x00, 0x80, 0x03, 0x0F, 0x00, 0x00, 0x02, 0x03, // 67
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0xFF, 0x3F, 0x00, 0xE0, 0xFF, 0x3F, 0x00, 0x60, 0x00, 0x30, 0x00, 0x60, 0x00, 0x30, 0x00, 0x60, 0x00, 0x30, 0x00, 0x60, 0x00, 0x30, 0x00, 0x60, 0x00, 0x30, 0x00, 0x60, 0x00, 0x30, 0x00, 0x60, 0x00, 0x30, 0x00, 0xE0, 0x00, 0x18, 0x00, 0xC0, 0x01, 0x1C, 0x00, 0x80, 0x03, 0x0E, 0x00, 0x00, 0xFF, 0x07, 0x00, 0x00, 0xFC, 0x01, // 68
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0xFF, 0x3F, 0x00, 0xE0, 0xFF, 0x3F, 0x00, 0x60, 0x30, 0x30, 0x00, 0x60, 0x30, 0x30, 0x00, 0x60, 0x30, 0x30, 0x00, 0x60, 0x30, 0x30, 0x00, 0x60, 0x30, 0x30, 0x00, 0x60, 0x30, 0x30, 0x00, 0x60, 0x30, 0x30, 0x00, 0x60, 0x30, 0x30, 0x00, 0x60, 0x30, 0x30, 0x00, 0x60, 0x30, 0x30, 0x00, 0x60, 0x00, 0x30, // 69
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0xFF, 0x3F, 0x00, 0xE0, 0xFF, 0x3F, 0x00, 0x60, 0x30, 0x00, 0x00, 0x60, 0x30, 0x00, 0x00, 0x60, 0x30, 0x00, 0x00, 0x60, 0x30, 0x00, 0x00, 0x60, 0x30, 0x00, 0x00, 0x60, 0x30, 0x00, 0x00, 0x60, 0x30, 0x00, 0x00, 0x60, 0x30, 0x00, 0x00, 0x60, 0x30, 0x00, 0x00, 0x60, // 70
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 0x01, 0x00, 0x00, 0xFF, 0x07, 0x00, 0x80, 0x07, 0x0F, 0x00, 0xC0, 0x01, 0x1C, 0x00, 0xC0, 0x00, 0x18, 0x00, 0xE0, 0x00, 0x18, 0x00, 0x60, 0x00, 0x30, 0x00, 0x60, 0x00, 0x30, 0x00, 0x60, 0x00, 0x30, 0x00, 0x60, 0x60, 0x30, 0x00, 0x60, 0x60, 0x30, 0x00, 0xE0, 0x60, 0x38, 0x00, 0xC0, 0x60, 0x18, 0x00, 0xC0, 0x61, 0x18, 0x00, 0x80, 0xE3, 0x0F, 0x00, 0x00, 0xE2, 0x0F, // 71
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0xFF, 0x3F, 0x00, 0xE0, 0xFF, 0x3F, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0xE0, 0xFF, 0x3F, 0x00, 0xE0, 0xFF, 0x3F, // 72
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0xFF, 0x3F, 0x00, 0xE0, 0xFF, 0x3F, // 73
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x1E, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x38, 0x00, 0xE0, 0xFF, 0x1F, 0x00, 0xE0, 0xFF, 0x0F, // 74
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0xFF, 0x3F, 0x00, 0xE0, 0xFF, 0x3F, 0x00, 0x00, 0xE0, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x7C, 0x00, 0x00, 0x00, 0xFE, 0x00, 0x00, 0x00, 0xE7, 0x01, 0x00, 0x80, 0x83, 0x07, 0x00, 0xC0, 0x01, 0x0F, 0x00, 0xE0, 0x00, 0x1E, 0x00, 0x60, 0x00, 0x38, 0x00, 0x20, 0x00, 0x30, 0x00, 0x00, 0x00, 0x20, // 75
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0xFF, 0x3F, 0x00, 0xE0, 0xFF, 0x3F, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x30, // 76
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0xFF, 0x3F, 0x00, 0xE0, 0xFF, 0x3F, 0x00, 0xE0, 0x01, 0x00, 0x00, 0xC0, 0x0F, 0x00, 0x00, 0x00, 0xFE, 0x00, 0x00, 0x00, 0xE0, 0x07, 0x00, 0x00, 0x00, 0x3F, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x3F, 0x00, 0x00, 0xE0, 0x07, 0x00, 0x00, 0xFE, 0x00, 0x00, 0xC0, 0x0F, 0x00, 0x00, 0xE0, 0x01, 0x00, 0x00, 0xE0, 0xFF, 0x3F, 0x00, 0xE0, 0xFF, 0x3F, // 77
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0xFF, 0x3F, 0x00, 0xE0, 0xFF, 0x3F, 0x00, 0xC0, 0x01, 0x00, 0x00, 0x80, 0x03, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0xE0, 0x01, 0x00, 0x00, 0x80, 0x03, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x1C, 0x00, 0xE0, 0xFF, 0x3F, 0x00, 0xE0, 0xFF, 0x3F, // 78
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 0x01, 0x00, 0x00, 0xFF, 0x07, 0x00, 0x80, 0x07, 0x0F, 0x00, 0xC0, 0x01, 0x1C, 0x00, 0xC0, 0x00, 0x18, 0x00, 0xE0, 0x00, 0x38, 0x00, 0x60, 0x00, 0x30, 0x00, 0x60, 0x00, 0x30, 0x00, 0x60, 0x00, 0x30, 0x00, 0x60, 0x00, 0x30, 0x00, 0x60, 0x00, 0x30, 0x00, 0xE0, 0x00, 0x38, 0x00, 0xC0, 0x00, 0x18, 0x00, 0xC0, 0x01, 0x1C, 0x00, 0x80, 0x07, 0x0F, 0x00, 0x00, 0xFF, 0x07, 0x00, 0x00, 0xFC, 0x01, // 79
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0xFF, 0x3F, 0x00, 0xE0, 0xFF, 0x3F, 0x00, 0x60, 0x60, 0x00, 0x00, 0x60, 0x60, 0x00, 0x00, 0x60, 0x60, 0x00, 0x00, 0x60, 0x60, 0x00, 0x00, 0x60, 0x60, 0x00, 0x00, 0x60, 0x60, 0x00, 0x00, 0x60, 0x60, 0x00, 0x00, 0x60, 0x60, 0x00, 0x00, 0xC0, 0x30, 0x00, 0x00, 0xC0, 0x3F, 0x00, 0x00, 0x00, 0x0F, // 80
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 0x01, 0x00, 0x00, 0xFF, 0x07, 0x00, 0x80, 0x07, 0x0F, 0x00, 0xC0, 0x01, 0x0C, 0x00, 0xC0, 0x00, 0x18, 0x00, 0xE0, 0x00, 0x18, 0x00, 0x60, 0x00, 0x30, 0x00, 0x60, 0x00, 0x30, 0x00, 0x60, 0x00, 0x30, 0x00, 0x60, 0x00, 0x36, 0x00, 0x60, 0x00, 0x36, 0x00, 0xE0, 0x00, 0x3C, 0x00, 0xC0, 0x00, 0x1C, 0x00, 0xC0, 0x01, 0x1C, 0x00, 0x80, 0x07, 0x3F, 0x00, 0x00, 0xFF, 0x77, 0x00, 0x00, 0xFC, 0x61, // 81
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0xFF, 0x3F, 0x00, 0xE0, 0xFF, 0x3F, 0x00, 0x60, 0x30, 0x00, 0x00, 0x60, 0x30, 0x00, 0x00, 0x60, 0x30, 0x00, 0x00, 0x60, 0x30, 0x00, 0x00, 0x60, 0x70, 0x00, 0x00, 0x60, 0xF0, 0x00, 0x00, 0x60, 0xF0, 0x03, 0x00, 0x60, 0xB0, 0x07, 0x00, 0xE0, 0x18, 0x1F, 0x00, 0xC0, 0x1F, 0x3C, 0x00, 0x80, 0x0F, 0x30, 0x00, 0x00, 0x00, 0x20, // 82
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x07, 0x0F, 0x00, 0xC0, 0x1F, 0x1C, 0x00, 0xC0, 0x18, 0x18, 0x00, 0x60, 0x38, 0x38, 0x00, 0x60, 0x30, 0x30, 0x00, 0x60, 0x30, 0x30, 0x00, 0x60, 0x30, 0x30, 0x00, 0x60, 0x30, 0x30, 0x00, 0x60, 0x70, 0x30, 0x00, 0xC0, 0x60, 0x18, 0x00, 0xC0, 0xE1, 0x18, 0x00, 0x80, 0xC3, 0x0F, 0x00, 0x00, 0x83, 0x07, // 83
+ 0x60, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0xE0, 0xFF, 0x3F, 0x00, 0xE0, 0xFF, 0x3F, 0x00, 0x60, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x60, // 84
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0xFF, 0x03, 0x00, 0xE0, 0xFF, 0x0F, 0x00, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x1C, 0x00, 0xE0, 0xFF, 0x0F, 0x00, 0xE0, 0xFF, 0x03, // 85
+ 0x20, 0x00, 0x00, 0x00, 0xE0, 0x01, 0x00, 0x00, 0xC0, 0x0F, 0x00, 0x00, 0x00, 0x3E, 0x00, 0x00, 0x00, 0xF8, 0x01, 0x00, 0x00, 0xC0, 0x0F, 0x00, 0x00, 0x00, 0x3E, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x3E, 0x00, 0x00, 0xC0, 0x0F, 0x00, 0x00, 0xF8, 0x01, 0x00, 0x00, 0x3E, 0x00, 0x00, 0xC0, 0x0F, 0x00, 0x00, 0xE0, 0x01, 0x00, 0x00, 0x20, // 86
+ 0x60, 0x00, 0x00, 0x00, 0xE0, 0x07, 0x00, 0x00, 0x80, 0xFF, 0x00, 0x00, 0x00, 0xF8, 0x0F, 0x00, 0x00, 0x80, 0x3F, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x3F, 0x00, 0x00, 0xE0, 0x0F, 0x00, 0x00, 0xFC, 0x01, 0x00, 0x80, 0x1F, 0x00, 0x00, 0xE0, 0x03, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0xE0, 0x03, 0x00, 0x00, 0x80, 0x1F, 0x00, 0x00, 0x00, 0xFC, 0x01, 0x00, 0x00, 0xE0, 0x0F, 0x00, 0x00, 0x00, 0x3F, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x80, 0x3F, 0x00, 0x00, 0xF8, 0x0F, 0x00, 0x80, 0xFF, 0x00, 0x00, 0xE0, 0x07, 0x00, 0x00, 0x60, // 87
+ 0x00, 0x00, 0x20, 0x00, 0x20, 0x00, 0x30, 0x00, 0x60, 0x00, 0x3C, 0x00, 0xE0, 0x01, 0x1E, 0x00, 0xC0, 0x83, 0x07, 0x00, 0x00, 0xCF, 0x03, 0x00, 0x00, 0xFE, 0x01, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0xFE, 0x01, 0x00, 0x00, 0xCF, 0x03, 0x00, 0xC0, 0x03, 0x07, 0x00, 0xE0, 0x01, 0x1E, 0x00, 0x60, 0x00, 0x3C, 0x00, 0x20, 0x00, 0x30, 0x00, 0x00, 0x00, 0x20, // 88
+ 0x20, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0xC0, 0x01, 0x00, 0x00, 0x80, 0x03, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x1E, 0x00, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x00, 0xF0, 0x3F, 0x00, 0x00, 0xF0, 0x3F, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x00, 0x1E, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0xE0, 0x01, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x20, // 89
+ 0x00, 0x00, 0x30, 0x00, 0x60, 0x00, 0x38, 0x00, 0x60, 0x00, 0x3C, 0x00, 0x60, 0x00, 0x37, 0x00, 0x60, 0x80, 0x33, 0x00, 0x60, 0xC0, 0x31, 0x00, 0x60, 0xE0, 0x30, 0x00, 0x60, 0x38, 0x30, 0x00, 0x60, 0x1C, 0x30, 0x00, 0x60, 0x0E, 0x30, 0x00, 0x60, 0x07, 0x30, 0x00, 0xE0, 0x01, 0x30, 0x00, 0xE0, 0x00, 0x30, 0x00, 0x60, 0x00, 0x30, // 90
+ 0x00, 0x00, 0x00, 0x00, 0xE0, 0xFF, 0xFF, 0x07, 0xE0, 0xFF, 0xFF, 0x07, 0x60, 0x00, 0x00, 0x06, 0x60, 0x00, 0x00, 0x06, // 91
+ 0x60, 0x00, 0x00, 0x00, 0xE0, 0x03, 0x00, 0x00, 0x80, 0x3F, 0x00, 0x00, 0x00, 0xFC, 0x01, 0x00, 0x00, 0xE0, 0x0F, 0x00, 0x00, 0x00, 0x3E, 0x00, 0x00, 0x00, 0x30, // 92
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x06, 0x60, 0x00, 0x00, 0x06, 0xE0, 0xFF, 0xFF, 0x07, 0xE0, 0xFF, 0xFF, 0x07, // 93
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x1F, 0x00, 0x00, 0xC0, 0x07, 0x00, 0x00, 0xE0, 0x00, 0x00, 0x00, 0xE0, 0x00, 0x00, 0x00, 0xC0, 0x07, 0x00, 0x00, 0x00, 0x1F, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x20, // 94
+ 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x06, // 95
+ 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0xE0, 0x00, 0x00, 0x00, 0x80, // 96
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x0E, 0x00, 0x00, 0x1C, 0x1F, 0x00, 0x00, 0x8C, 0x39, 0x00, 0x00, 0x86, 0x31, 0x00, 0x00, 0x86, 0x31, 0x00, 0x00, 0xC6, 0x30, 0x00, 0x00, 0xC6, 0x18, 0x00, 0x00, 0xCE, 0x0C, 0x00, 0x00, 0xFC, 0x1F, 0x00, 0x00, 0xF8, 0x3F, 0x00, 0x00, 0x00, 0x20, // 97
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0xFF, 0x3F, 0x00, 0xE0, 0xFF, 0x3F, 0x00, 0x00, 0x18, 0x0C, 0x00, 0x00, 0x0C, 0x18, 0x00, 0x00, 0x06, 0x30, 0x00, 0x00, 0x06, 0x30, 0x00, 0x00, 0x06, 0x30, 0x00, 0x00, 0x0E, 0x38, 0x00, 0x00, 0x1C, 0x1C, 0x00, 0x00, 0xF8, 0x0F, 0x00, 0x00, 0xE0, 0x03, // 98
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x07, 0x00, 0x00, 0xF8, 0x0F, 0x00, 0x00, 0x1C, 0x1C, 0x00, 0x00, 0x0E, 0x38, 0x00, 0x00, 0x06, 0x30, 0x00, 0x00, 0x06, 0x30, 0x00, 0x00, 0x06, 0x30, 0x00, 0x00, 0x0E, 0x38, 0x00, 0x00, 0x1C, 0x1C, 0x00, 0x00, 0x18, 0x0C, // 99
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0x03, 0x00, 0x00, 0xF8, 0x0F, 0x00, 0x00, 0x1C, 0x1C, 0x00, 0x00, 0x0E, 0x38, 0x00, 0x00, 0x06, 0x30, 0x00, 0x00, 0x06, 0x30, 0x00, 0x00, 0x06, 0x30, 0x00, 0x00, 0x0C, 0x18, 0x00, 0x00, 0x18, 0x0C, 0x00, 0xE0, 0xFF, 0x3F, 0x00, 0xE0, 0xFF, 0x3F, // 100
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0x07, 0x00, 0x00, 0xF8, 0x0F, 0x00, 0x00, 0xDC, 0x1C, 0x00, 0x00, 0xCE, 0x38, 0x00, 0x00, 0xC6, 0x30, 0x00, 0x00, 0xC6, 0x30, 0x00, 0x00, 0xC6, 0x30, 0x00, 0x00, 0xCE, 0x38, 0x00, 0x00, 0xDC, 0x18, 0x00, 0x00, 0xF8, 0x0C, 0x00, 0x00, 0xF0, 0x04, // 101
+ 0x00, 0x06, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0xC0, 0xFF, 0x3F, 0x00, 0xE0, 0xFF, 0x3F, 0x00, 0x60, 0x06, 0x00, 0x00, 0x60, 0x06, 0x00, 0x00, 0x60, 0x06, // 102
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0x83, 0x01, 0x00, 0xF8, 0x8F, 0x03, 0x00, 0x1C, 0x1C, 0x07, 0x00, 0x0E, 0x38, 0x06, 0x00, 0x06, 0x30, 0x06, 0x00, 0x06, 0x30, 0x06, 0x00, 0x06, 0x30, 0x06, 0x00, 0x0C, 0x18, 0x07, 0x00, 0x18, 0x8C, 0x03, 0x00, 0xFE, 0xFF, 0x01, 0x00, 0xFE, 0xFF, // 103
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0xFF, 0x3F, 0x00, 0xE0, 0xFF, 0x3F, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0xFC, 0x3F, 0x00, 0x00, 0xF8, 0x3F, // 104
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0xFE, 0x3F, 0x00, 0x60, 0xFE, 0x3F, // 105
+ 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x06, 0x60, 0xFE, 0xFF, 0x07, 0x60, 0xFE, 0xFF, 0x03, // 106
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0xFF, 0x3F, 0x00, 0xE0, 0xFF, 0x3F, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0xE0, 0x00, 0x00, 0x00, 0xF0, 0x01, 0x00, 0x00, 0x98, 0x07, 0x00, 0x00, 0x0C, 0x0E, 0x00, 0x00, 0x06, 0x3C, 0x00, 0x00, 0x02, 0x30, 0x00, 0x00, 0x00, 0x20, // 107
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0xFF, 0x3F, 0x00, 0xE0, 0xFF, 0x3F, // 108
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0x3F, 0x00, 0x00, 0xFE, 0x3F, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0xFC, 0x3F, 0x00, 0x00, 0xF8, 0x3F, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0xFC, 0x3F, 0x00, 0x00, 0xF8, 0x3F, // 109
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0x3F, 0x00, 0x00, 0xFE, 0x3F, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0xFC, 0x3F, 0x00, 0x00, 0xF8, 0x3F, // 110
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x07, 0x00, 0x00, 0xF8, 0x0F, 0x00, 0x00, 0x1C, 0x1C, 0x00, 0x00, 0x0E, 0x38, 0x00, 0x00, 0x06, 0x30, 0x00, 0x00, 0x06, 0x30, 0x00, 0x00, 0x06, 0x30, 0x00, 0x00, 0x0E, 0x38, 0x00, 0x00, 0x1C, 0x1C, 0x00, 0x00, 0xF8, 0x0F, 0x00, 0x00, 0xF0, 0x07, // 111
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0xFF, 0x07, 0x00, 0xFE, 0xFF, 0x07, 0x00, 0x18, 0x0C, 0x00, 0x00, 0x0C, 0x18, 0x00, 0x00, 0x06, 0x30, 0x00, 0x00, 0x06, 0x30, 0x00, 0x00, 0x06, 0x30, 0x00, 0x00, 0x0E, 0x38, 0x00, 0x00, 0x1C, 0x1C, 0x00, 0x00, 0xF8, 0x0F, 0x00, 0x00, 0xE0, 0x03, // 112
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0x03, 0x00, 0x00, 0xF8, 0x0F, 0x00, 0x00, 0x1C, 0x1C, 0x00, 0x00, 0x0E, 0x38, 0x00, 0x00, 0x06, 0x30, 0x00, 0x00, 0x06, 0x30, 0x00, 0x00, 0x06, 0x30, 0x00, 0x00, 0x0C, 0x18, 0x00, 0x00, 0x18, 0x0C, 0x00, 0x00, 0xFE, 0xFF, 0x07, 0x00, 0xFE, 0xFF, 0x07, // 113
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0x3F, 0x00, 0x00, 0xFE, 0x3F, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x06, // 114
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x0C, 0x00, 0x00, 0x7C, 0x1C, 0x00, 0x00, 0xEE, 0x38, 0x00, 0x00, 0xC6, 0x30, 0x00, 0x00, 0xC6, 0x30, 0x00, 0x00, 0xC6, 0x31, 0x00, 0x00, 0xC6, 0x31, 0x00, 0x00, 0x8E, 0x39, 0x00, 0x00, 0x9C, 0x1F, 0x00, 0x00, 0x18, 0x0F, // 115
+ 0x00, 0x06, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0xC0, 0xFF, 0x1F, 0x00, 0xE0, 0xFF, 0x3F, 0x00, 0x00, 0x06, 0x30, 0x00, 0x00, 0x06, 0x30, 0x00, 0x00, 0x06, 0x30, // 116
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0x0F, 0x00, 0x00, 0xFE, 0x1F, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0xFE, 0x3F, 0x00, 0x00, 0xFE, 0x3F, // 117
+ 0x00, 0x06, 0x00, 0x00, 0x00, 0x3E, 0x00, 0x00, 0x00, 0xF8, 0x00, 0x00, 0x00, 0xC0, 0x07, 0x00, 0x00, 0x00, 0x1F, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x1F, 0x00, 0x00, 0xC0, 0x07, 0x00, 0x00, 0xF8, 0x00, 0x00, 0x00, 0x3E, 0x00, 0x00, 0x00, 0x06, // 118
+ 0x00, 0x0E, 0x00, 0x00, 0x00, 0x7E, 0x00, 0x00, 0x00, 0xF0, 0x03, 0x00, 0x00, 0x80, 0x1F, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x80, 0x1F, 0x00, 0x00, 0xE0, 0x03, 0x00, 0x00, 0x7C, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x7C, 0x00, 0x00, 0x00, 0xE0, 0x03, 0x00, 0x00, 0x80, 0x1F, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x80, 0x1F, 0x00, 0x00, 0xF0, 0x03, 0x00, 0x00, 0x7E, 0x00, 0x00, 0x00, 0x0E, // 119
+ 0x00, 0x02, 0x20, 0x00, 0x00, 0x06, 0x30, 0x00, 0x00, 0x1E, 0x3C, 0x00, 0x00, 0x38, 0x0E, 0x00, 0x00, 0xF0, 0x07, 0x00, 0x00, 0xC0, 0x01, 0x00, 0x00, 0xE0, 0x07, 0x00, 0x00, 0x38, 0x0E, 0x00, 0x00, 0x1C, 0x3C, 0x00, 0x00, 0x0E, 0x30, 0x00, 0x00, 0x02, 0x20, // 120
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x7E, 0x00, 0x06, 0x00, 0xF0, 0x01, 0x06, 0x00, 0x80, 0x0F, 0x07, 0x00, 0x00, 0xFE, 0x03, 0x00, 0x00, 0xFC, 0x00, 0x00, 0xC0, 0x1F, 0x00, 0x00, 0xF8, 0x03, 0x00, 0x00, 0x3E, 0x00, 0x00, 0x00, 0x06, // 121
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x06, 0x3C, 0x00, 0x00, 0x06, 0x3E, 0x00, 0x00, 0x06, 0x37, 0x00, 0x00, 0xC6, 0x33, 0x00, 0x00, 0xE6, 0x30, 0x00, 0x00, 0x76, 0x30, 0x00, 0x00, 0x3E, 0x30, 0x00, 0x00, 0x1E, 0x30, 0x00, 0x00, 0x06, 0x30, // 122
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0xC0, 0x03, 0x00, 0xC0, 0x7F, 0xFE, 0x03, 0xE0, 0x3F, 0xFC, 0x07, 0x60, 0x00, 0x00, 0x06, 0x60, 0x00, 0x00, 0x06, // 123
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0xFF, 0xFF, 0x0F, 0xE0, 0xFF, 0xFF, 0x0F, // 124
+ 0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x06, 0x60, 0x00, 0x00, 0x06, 0xE0, 0x3F, 0xFC, 0x07, 0xC0, 0x7F, 0xFF, 0x03, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x80, 0x01, // 125
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0xE0, 0x00, 0x00, 0x00, 0x60, // 126
+ 0x00, 0x60, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0xE0, 0xFF, 0x3F, 0x00, 0xE0, 0xFF, 0x3F, 0x00, 0x00, 0x0C, 0x30, 0x00, 0x00, 0x06, 0x30, 0x00, 0x00, 0x03, 0x30, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x30, // 129
+ 0x00, 0x60, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0xE0, 0xFF, 0x3F, 0x00, 0xE0, 0xFF, 0x3F, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x06, // 130
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0xFF, 0x3F, 0x00, 0xE0, 0xFF, 0x3F, 0x00, 0xC0, 0x01, 0x00, 0x00, 0x80, 0x03, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x10, 0x3C, 0x00, 0x00, 0x1C, 0x70, 0x00, 0x00, 0x0C, 0xE0, 0x01, 0x00, 0x04, 0x80, 0x03, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x1C, 0x00, 0xE0, 0xFF, 0x3F, 0x00, 0xE0, 0xFF, 0x3F, // 131
+ 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x3E, 0x00, 0x00, 0x80, 0x0F, 0x00, 0x00, 0xF0, 0x03, 0x00, 0x00, 0xFE, 0x01, 0x00, 0x80, 0x8F, 0x01, 0x00, 0xE0, 0x83, 0x01, 0x00, 0x60, 0x80, 0x01, 0x00, 0xE0, 0x83, 0x01, 0x00, 0x80, 0x8F, 0x01, 0x00, 0x00, 0xFE, 0x01, 0x00, 0x00, 0xF0, 0x03, 0x00, 0x00, 0x80, 0x0F, 0x00, 0x00, 0x00, 0xFE, 0x01, 0x00, 0x00, 0xB0, 0x03, 0x00, 0x00, 0x00, 0x03, // 132
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x0E, 0x00, 0x00, 0x1C, 0x1F, 0x00, 0x00, 0x8C, 0x39, 0x00, 0x00, 0x86, 0x31, 0x00, 0x00, 0x86, 0x31, 0x00, 0x00, 0xC6, 0x30, 0x00, 0x00, 0xC6, 0x18, 0x00, 0x00, 0xCE, 0x0C, 0x00, 0x00, 0xFC, 0x1F, 0x00, 0x00, 0xF8, 0xFF, 0x01, 0x00, 0x00, 0xA0, 0x03, 0x00, 0x00, 0x00, 0x03, // 133
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 0x01, 0x00, 0x00, 0xFF, 0x07, 0x00, 0x80, 0x07, 0x0F, 0x00, 0xC0, 0x01, 0x1C, 0x00, 0xC0, 0x00, 0x18, 0x00, 0x60, 0x00, 0x30, 0x00, 0x60, 0x00, 0x30, 0x00, 0x68, 0x00, 0x30, 0x00, 0x6E, 0x00, 0x30, 0x00, 0x66, 0x00, 0x30, 0x00, 0x62, 0x00, 0x30, 0x00, 0xC0, 0x00, 0x18, 0x00, 0xC0, 0x01, 0x1C, 0x00, 0x80, 0x03, 0x0F, 0x00, 0x00, 0x02, 0x03, // 134
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x07, 0x00, 0x00, 0xF8, 0x0F, 0x00, 0x00, 0x1C, 0x1C, 0x00, 0x00, 0x0E, 0x38, 0x00, 0x80, 0x06, 0x30, 0x00, 0xE0, 0x06, 0x30, 0x00, 0x60, 0x06, 0x30, 0x00, 0x20, 0x0E, 0x38, 0x00, 0x00, 0x1C, 0x1C, 0x00, 0x00, 0x18, 0x0C, // 135
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0x3F, 0x00, 0x00, 0xFE, 0x3F, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x80, 0x06, 0x00, 0x00, 0xE0, 0x06, 0x00, 0x00, 0x60, 0x06, 0x00, 0x00, 0x20, 0x0E, 0x00, 0x00, 0x00, 0xFC, 0x3F, 0x00, 0x00, 0xF8, 0x3F, // 136
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x06, 0x3C, 0x00, 0x00, 0x06, 0x3E, 0x00, 0x00, 0x06, 0x37, 0x00, 0x80, 0xC6, 0x33, 0x00, 0xE0, 0xE6, 0x30, 0x00, 0x60, 0x76, 0x30, 0x00, 0x20, 0x3E, 0x30, 0x00, 0x00, 0x1E, 0x30, 0x00, 0x00, 0x06, 0x30, // 137
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 0x01, 0x00, 0x00, 0xFF, 0x07, 0x00, 0x80, 0x07, 0x0F, 0x00, 0xC0, 0x01, 0x1C, 0x00, 0xC0, 0x00, 0x18, 0x00, 0xE0, 0x00, 0x38, 0x00, 0x60, 0x00, 0x30, 0x00, 0x60, 0x00, 0x30, 0x00, 0x68, 0x00, 0x30, 0x00, 0x6E, 0x00, 0x30, 0x00, 0x66, 0x00, 0x30, 0x00, 0xE2, 0x00, 0x38, 0x00, 0xC0, 0x00, 0x18, 0x00, 0xC0, 0x01, 0x1C, 0x00, 0x80, 0x07, 0x0F, 0x00, 0x00, 0xFF, 0x07, 0x00, 0x00, 0xFC, 0x01, // 147
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x07, 0x00, 0x00, 0xF8, 0x0F, 0x00, 0x00, 0x1C, 0x1C, 0x00, 0x00, 0x0E, 0x38, 0x00, 0x00, 0x06, 0x30, 0x00, 0x80, 0x06, 0x30, 0x00, 0xE0, 0x06, 0x30, 0x00, 0x60, 0x0E, 0x38, 0x00, 0x20, 0x1C, 0x1C, 0x00, 0x00, 0xF8, 0x0F, 0x00, 0x00, 0xF0, 0x07, // 148
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0xFF, 0x3F, 0x00, 0xE0, 0xFF, 0x3F, 0x00, 0x60, 0x30, 0x30, 0x00, 0x60, 0x30, 0x30, 0x00, 0x60, 0x30, 0x30, 0x00, 0x60, 0x30, 0x30, 0x00, 0x60, 0x30, 0xF0, 0x01, 0x60, 0x30, 0xB0, 0x03, 0x60, 0x30, 0x30, 0x03, 0x60, 0x30, 0x30, 0x00, 0x60, 0x30, 0x30, 0x00, 0x60, 0x30, 0x30, 0x00, 0x60, 0x00, 0x30, // 152
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0x07, 0x00, 0x00, 0xF8, 0x0F, 0x00, 0x00, 0xDC, 0x1C, 0x00, 0x00, 0xCE, 0x38, 0x00, 0x00, 0xC6, 0x30, 0x00, 0x00, 0xC6, 0xF0, 0x01, 0x00, 0xC6, 0xB0, 0x03, 0x00, 0xCE, 0x38, 0x03, 0x00, 0xDC, 0x18, 0x00, 0x00, 0xF8, 0x0C, 0x00, 0x00, 0xF0, 0x04, // 153
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x07, 0x0F, 0x00, 0xC0, 0x1F, 0x1C, 0x00, 0xC0, 0x18, 0x18, 0x00, 0x60, 0x38, 0x38, 0x00, 0x60, 0x30, 0x30, 0x00, 0x68, 0x30, 0x30, 0x00, 0x6E, 0x30, 0x30, 0x00, 0x66, 0x30, 0x30, 0x00, 0x62, 0x70, 0x30, 0x00, 0xC0, 0x60, 0x18, 0x00, 0xC0, 0xE1, 0x18, 0x00, 0x80, 0xC3, 0x0F, 0x00, 0x00, 0x83, 0x07, // 154
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x0C, 0x00, 0x00, 0x7C, 0x1C, 0x00, 0x00, 0xEE, 0x38, 0x00, 0x00, 0xC6, 0x30, 0x00, 0x80, 0xC6, 0x30, 0x00, 0xE0, 0xC6, 0x31, 0x00, 0x60, 0xC6, 0x31, 0x00, 0x20, 0x8E, 0x39, 0x00, 0x00, 0x9C, 0x1F, 0x00, 0x00, 0x18, 0x0F, // 155
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE6, 0xFF, 0x07, 0x00, 0xE6, 0xFF, 0x07, // 161
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0x07, 0x00, 0x00, 0xF8, 0x0F, 0x00, 0x00, 0x1C, 0x9C, 0x07, 0x00, 0x0E, 0x78, 0x00, 0x00, 0x06, 0x3F, 0x00, 0x00, 0xF6, 0x30, 0x00, 0x00, 0x0E, 0x30, 0x00, 0xE0, 0x0D, 0x1C, 0x00, 0x00, 0x1C, 0x0E, 0x00, 0x00, 0x10, 0x06, // 162
+ 0x00, 0x60, 0x10, 0x00, 0x00, 0x60, 0x38, 0x00, 0x00, 0x7F, 0x1C, 0x00, 0xC0, 0xFF, 0x1F, 0x00, 0xE0, 0xE0, 0x19, 0x00, 0x60, 0x60, 0x18, 0x00, 0x60, 0x60, 0x18, 0x00, 0x60, 0x60, 0x30, 0x00, 0xE0, 0x00, 0x30, 0x00, 0xC0, 0x01, 0x30, 0x00, 0x80, 0x01, 0x38, 0x00, 0x00, 0x00, 0x10, // 163
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x04, 0x00, 0x00, 0xF7, 0x0E, 0x00, 0x00, 0xFE, 0x07, 0x00, 0x00, 0x0C, 0x03, 0x00, 0x00, 0x06, 0x06, 0x00, 0x00, 0x06, 0x06, 0x00, 0x00, 0x06, 0x06, 0x00, 0x00, 0x06, 0x06, 0x00, 0x00, 0x0C, 0x03, 0x00, 0x00, 0xFE, 0x07, 0x00, 0x00, 0xF7, 0x0E, 0x00, 0x00, 0x02, 0x04, // 164
+ 0xE0, 0x60, 0x06, 0x00, 0xC0, 0x61, 0x06, 0x00, 0x80, 0x67, 0x06, 0x00, 0x00, 0x7E, 0x06, 0x00, 0x00, 0x7C, 0x06, 0x00, 0x00, 0xF0, 0x3F, 0x00, 0x00, 0xF0, 0x3F, 0x00, 0x00, 0x7C, 0x06, 0x00, 0x00, 0x7E, 0x06, 0x00, 0x80, 0x67, 0x06, 0x00, 0xC0, 0x61, 0x06, 0x00, 0xE0, 0x60, 0x06, 0x00, 0x20, // 165
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0x7F, 0xF8, 0x0F, 0xE0, 0x7F, 0xF8, 0x0F, // 166
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0x00, 0x00, 0x80, 0xF3, 0xC1, 0x00, 0xC0, 0x1F, 0xC3, 0x03, 0xE0, 0x0C, 0x07, 0x03, 0x60, 0x1C, 0x06, 0x06, 0x60, 0x18, 0x0C, 0x06, 0x60, 0x30, 0x1C, 0x06, 0xE0, 0x70, 0x38, 0x07, 0xC0, 0xE1, 0xF4, 0x03, 0x80, 0xC1, 0xE7, 0x01, 0x00, 0x80, 0x03, // 167
+ 0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x60, // 168
+ 0x00, 0xF8, 0x00, 0x00, 0x00, 0xFE, 0x03, 0x00, 0x00, 0x07, 0x07, 0x00, 0x80, 0x01, 0x0C, 0x00, 0xC0, 0x79, 0x1C, 0x00, 0xC0, 0xFE, 0x19, 0x00, 0x60, 0x86, 0x31, 0x00, 0x60, 0x03, 0x33, 0x00, 0x60, 0x03, 0x33, 0x00, 0x60, 0x03, 0x33, 0x00, 0x60, 0x03, 0x33, 0x00, 0x60, 0x87, 0x33, 0x00, 0xC0, 0x86, 0x19, 0x00, 0xC0, 0x85, 0x1C, 0x00, 0x80, 0x01, 0x0C, 0x00, 0x00, 0x07, 0x07, 0x00, 0x00, 0xFE, 0x03, 0x00, 0x00, 0xF8, // 169
+ 0x00, 0x00, 0x00, 0x00, 0xC0, 0x1C, 0x00, 0x00, 0xE0, 0x3E, 0x00, 0x00, 0x60, 0x32, 0x00, 0x00, 0x60, 0x32, 0x00, 0x00, 0xE0, 0x3F, 0x00, 0x00, 0xC0, 0x3F, // 170
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0xE0, 0x03, 0x00, 0x00, 0x78, 0x0F, 0x00, 0x00, 0x1C, 0x1C, 0x00, 0x00, 0x84, 0x10, 0x00, 0x00, 0xE0, 0x03, 0x00, 0x00, 0x78, 0x0F, 0x00, 0x00, 0x1C, 0x1C, 0x00, 0x00, 0x04, 0x10, // 171
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0xFC, 0x01, 0x00, 0x00, 0xFC, 0x01, // 172
+ 0x00, 0x80, 0x01, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x80, 0x01, // 173
+ 0x00, 0xF8, 0x00, 0x00, 0x00, 0xFE, 0x03, 0x00, 0x00, 0x07, 0x07, 0x00, 0x80, 0x01, 0x0C, 0x00, 0xC0, 0x01, 0x1C, 0x00, 0xC0, 0xFE, 0x1B, 0x00, 0x60, 0xFE, 0x33, 0x00, 0x60, 0x66, 0x30, 0x00, 0x60, 0x66, 0x30, 0x00, 0x60, 0xE6, 0x30, 0x00, 0x60, 0xFE, 0x31, 0x00, 0x60, 0x3C, 0x33, 0x00, 0xC0, 0x00, 0x1A, 0x00, 0xC0, 0x01, 0x1C, 0x00, 0x80, 0x01, 0x0C, 0x00, 0x00, 0x07, 0x07, 0x00, 0x00, 0xFE, 0x03, 0x00, 0x00, 0xF8, // 174
+ 0x0C, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x0C, // 175
+ 0x00, 0x00, 0x00, 0x00, 0x80, 0x03, 0x00, 0x00, 0x40, 0x04, 0x00, 0x00, 0x20, 0x08, 0x00, 0x00, 0x20, 0x08, 0x00, 0x00, 0x20, 0x08, 0x00, 0x00, 0x40, 0x04, 0x00, 0x00, 0x80, 0x03, // 176
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x30, 0x00, 0x00, 0x60, 0x30, 0x00, 0x00, 0x60, 0x30, 0x00, 0x00, 0x60, 0x30, 0x00, 0x00, 0x60, 0x30, 0x00, 0x00, 0xFF, 0x3F, 0x00, 0x00, 0xFF, 0x3F, 0x00, 0x00, 0x60, 0x30, 0x00, 0x00, 0x60, 0x30, 0x00, 0x00, 0x60, 0x30, 0x00, 0x00, 0x60, 0x30, 0x00, 0x00, 0x60, 0x30, // 177
+ 0x40, 0x20, 0x00, 0x00, 0x60, 0x30, 0x00, 0x00, 0x20, 0x38, 0x00, 0x00, 0x20, 0x2C, 0x00, 0x00, 0x20, 0x26, 0x00, 0x00, 0xE0, 0x23, 0x00, 0x00, 0xC0, 0x21, // 178
+ 0x40, 0x10, 0x00, 0x00, 0x60, 0x30, 0x00, 0x00, 0x20, 0x20, 0x00, 0x00, 0x20, 0x22, 0x00, 0x00, 0x20, 0x22, 0x00, 0x00, 0xE0, 0x3D, 0x00, 0x00, 0xC0, 0x1D, // 179
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0xE0, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x20, // 180
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0xFF, 0x07, 0x00, 0xFE, 0xFF, 0x07, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x1C, 0x00, 0x00, 0xFE, 0x3F, 0x00, 0x00, 0xFE, 0x3F, // 181
+ 0x00, 0x0F, 0x00, 0x00, 0xC0, 0x3F, 0x00, 0x00, 0xC0, 0x3F, 0x00, 0x00, 0xE0, 0x7F, 0x00, 0x00, 0xE0, 0x7F, 0x00, 0x00, 0xE0, 0xFF, 0xFF, 0x07, 0xE0, 0xFF, 0xFF, 0x07, 0x60, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0xE0, 0xFF, 0xFF, 0x07, 0xE0, 0xFF, 0xFF, 0x07, 0x60, 0x00, 0x00, 0x00, 0x60, // 182
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x60, // 183
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0xC0, 0x02, 0x00, 0x00, 0x80, 0x03, 0x00, 0x00, 0x00, 0x01, // 184
+ 0x00, 0x00, 0x30, 0x00, 0x60, 0x00, 0x38, 0x00, 0x60, 0x00, 0x3C, 0x00, 0x60, 0x00, 0x37, 0x00, 0x60, 0x80, 0x33, 0x00, 0x60, 0xC0, 0x31, 0x00, 0x68, 0xE0, 0x30, 0x00, 0x6E, 0x38, 0x30, 0x00, 0x66, 0x1C, 0x30, 0x00, 0x62, 0x0E, 0x30, 0x00, 0x60, 0x07, 0x30, 0x00, 0xE0, 0x01, 0x30, 0x00, 0xE0, 0x00, 0x30, 0x00, 0x60, 0x00, 0x30, // 185
+ 0x00, 0x00, 0x00, 0x00, 0x80, 0x0F, 0x00, 0x00, 0xC0, 0x1F, 0x00, 0x00, 0xE0, 0x38, 0x00, 0x00, 0x60, 0x30, 0x00, 0x00, 0xE0, 0x38, 0x00, 0x00, 0xC0, 0x1F, 0x00, 0x00, 0x80, 0x0F, // 186
+ 0x00, 0x00, 0x30, 0x00, 0x60, 0x00, 0x38, 0x00, 0x60, 0x00, 0x3C, 0x00, 0x60, 0x00, 0x37, 0x00, 0x60, 0x80, 0x33, 0x00, 0x60, 0xC0, 0x31, 0x00, 0x6C, 0xE0, 0x30, 0x00, 0x6C, 0x38, 0x30, 0x00, 0x60, 0x1C, 0x30, 0x00, 0x60, 0x0E, 0x30, 0x00, 0x60, 0x07, 0x30, 0x00, 0xE0, 0x01, 0x30, 0x00, 0xE0, 0x00, 0x30, 0x00, 0x60, 0x00, 0x30, // 187
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x06, 0x3C, 0x00, 0x00, 0x06, 0x3E, 0x00, 0x00, 0x06, 0x37, 0x00, 0xC0, 0xC6, 0x33, 0x00, 0xC0, 0xE6, 0x30, 0x00, 0x00, 0x76, 0x30, 0x00, 0x00, 0x3E, 0x30, 0x00, 0x00, 0x1E, 0x30, 0x00, 0x00, 0x06, 0x30, // 188
+ 0x00, 0x00, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x20, 0x00, 0xE0, 0x3F, 0x30, 0x00, 0xE0, 0x3F, 0x1C, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0xC0, 0x01, 0x00, 0x00, 0xE0, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x00, 0x4E, 0x20, 0x00, 0x00, 0x67, 0x30, 0x00, 0xC0, 0x21, 0x38, 0x00, 0xE0, 0x20, 0x2C, 0x00, 0x60, 0x20, 0x26, 0x00, 0x00, 0xE0, 0x27, 0x00, 0x00, 0xC0, 0x21, // 189
+ 0x40, 0x10, 0x00, 0x00, 0x60, 0x30, 0x00, 0x00, 0x20, 0x20, 0x00, 0x00, 0x20, 0x22, 0x20, 0x00, 0x20, 0x22, 0x30, 0x00, 0xE0, 0x3D, 0x38, 0x00, 0xC0, 0x1D, 0x0E, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x80, 0x03, 0x00, 0x00, 0xE0, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x0E, 0x0C, 0x00, 0x00, 0x07, 0x0E, 0x00, 0x80, 0x83, 0x0B, 0x00, 0xE0, 0xC0, 0x08, 0x00, 0x60, 0xE0, 0x3F, 0x00, 0x20, 0xE0, 0x3F, 0x00, 0x00, 0x00, 0x08, // 190
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x00, 0x00, 0x00, 0xF8, 0x03, 0x00, 0x00, 0x1E, 0x03, 0x00, 0x00, 0x07, 0x07, 0x00, 0xE6, 0x03, 0x06, 0x00, 0xE6, 0x01, 0x06, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x80, 0x03, 0x00, 0x00, 0xC0, 0x01, 0x00, 0x00, 0xC0, // 191
+ 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x3E, 0x00, 0x00, 0x80, 0x0F, 0x00, 0x00, 0xF0, 0x03, 0x00, 0x00, 0xFE, 0x01, 0x00, 0x82, 0x8F, 0x01, 0x00, 0xE6, 0x83, 0x01, 0x00, 0x6E, 0x80, 0x01, 0x00, 0xE8, 0x83, 0x01, 0x00, 0x80, 0x8F, 0x01, 0x00, 0x00, 0xFE, 0x01, 0x00, 0x00, 0xF0, 0x03, 0x00, 0x00, 0x80, 0x0F, 0x00, 0x00, 0x00, 0x3E, 0x00, 0x00, 0x00, 0x30, // 192
+ 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x3E, 0x00, 0x00, 0x80, 0x0F, 0x00, 0x00, 0xF0, 0x03, 0x00, 0x00, 0xFE, 0x01, 0x00, 0x80, 0x8F, 0x01, 0x00, 0xE8, 0x83, 0x01, 0x00, 0x6E, 0x80, 0x01, 0x00, 0xE6, 0x83, 0x01, 0x00, 0x82, 0x8F, 0x01, 0x00, 0x00, 0xFE, 0x01, 0x00, 0x00, 0xF0, 0x03, 0x00, 0x00, 0x80, 0x0F, 0x00, 0x00, 0x00, 0x3E, 0x00, 0x00, 0x00, 0x30, // 193
+ 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x3E, 0x00, 0x00, 0x80, 0x0F, 0x00, 0x00, 0xF0, 0x03, 0x00, 0x00, 0xFE, 0x01, 0x00, 0x88, 0x8F, 0x01, 0x00, 0xEC, 0x83, 0x01, 0x00, 0x66, 0x80, 0x01, 0x00, 0xE6, 0x83, 0x01, 0x00, 0x8C, 0x8F, 0x01, 0x00, 0x08, 0xFE, 0x01, 0x00, 0x00, 0xF0, 0x03, 0x00, 0x00, 0x80, 0x0F, 0x00, 0x00, 0x00, 0x3E, 0x00, 0x00, 0x00, 0x30, // 194
+ 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x3E, 0x00, 0x00, 0x80, 0x0F, 0x00, 0x00, 0xF0, 0x03, 0x00, 0x0C, 0xFE, 0x01, 0x00, 0x8E, 0x8F, 0x01, 0x00, 0xE6, 0x83, 0x01, 0x00, 0x66, 0x80, 0x01, 0x00, 0xEC, 0x83, 0x01, 0x00, 0x8C, 0x8F, 0x01, 0x00, 0x0E, 0xFE, 0x01, 0x00, 0x06, 0xF0, 0x03, 0x00, 0x00, 0x80, 0x0F, 0x00, 0x00, 0x00, 0x3E, 0x00, 0x00, 0x00, 0x30, // 195
+ 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x3E, 0x00, 0x00, 0x80, 0x0F, 0x00, 0x00, 0xF0, 0x03, 0x00, 0x00, 0xFE, 0x01, 0x00, 0x8C, 0x8F, 0x01, 0x00, 0xEC, 0x83, 0x01, 0x00, 0x60, 0x80, 0x01, 0x00, 0xE0, 0x83, 0x01, 0x00, 0x8C, 0x8F, 0x01, 0x00, 0x0C, 0xFE, 0x01, 0x00, 0x00, 0xF0, 0x03, 0x00, 0x00, 0x80, 0x0F, 0x00, 0x00, 0x00, 0x3E, 0x00, 0x00, 0x00, 0x30, // 196
+ 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x3E, 0x00, 0x00, 0x80, 0x0F, 0x00, 0x00, 0xF0, 0x03, 0x00, 0x00, 0xFE, 0x01, 0x00, 0x9C, 0x8F, 0x01, 0x00, 0xE2, 0x83, 0x01, 0x00, 0x62, 0x80, 0x01, 0x00, 0xE2, 0x83, 0x01, 0x00, 0x9C, 0x8F, 0x01, 0x00, 0x00, 0xFE, 0x01, 0x00, 0x00, 0xF0, 0x03, 0x00, 0x00, 0x80, 0x0F, 0x00, 0x00, 0x00, 0x3E, 0x00, 0x00, 0x00, 0x30, // 197
+ 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0xF0, 0x01, 0x00, 0x00, 0xBC, 0x01, 0x00, 0x00, 0x8F, 0x01, 0x00, 0xC0, 0x83, 0x01, 0x00, 0xE0, 0x80, 0x01, 0x00, 0x60, 0x80, 0x01, 0x00, 0x60, 0x80, 0x01, 0x00, 0xE0, 0xFF, 0x3F, 0x00, 0xE0, 0xFF, 0x3F, 0x00, 0x60, 0x30, 0x30, 0x00, 0x60, 0x30, 0x30, 0x00, 0x60, 0x30, 0x30, 0x00, 0x60, 0x30, 0x30, 0x00, 0x60, 0x30, 0x30, 0x00, 0x60, 0x30, 0x30, 0x00, 0x60, 0x30, 0x30, 0x00, 0x60, 0x30, 0x30, 0x00, 0x60, 0x30, 0x30, 0x00, 0x60, 0x00, 0x30, // 198
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 0x01, 0x00, 0x00, 0xFF, 0x07, 0x00, 0x80, 0x07, 0x0F, 0x00, 0xC0, 0x01, 0x1C, 0x00, 0xC0, 0x00, 0x18, 0x00, 0x60, 0x00, 0x30, 0x02, 0x60, 0x00, 0x30, 0x02, 0x60, 0x00, 0xF0, 0x02, 0x60, 0x00, 0xB0, 0x03, 0x60, 0x00, 0x30, 0x01, 0x60, 0x00, 0x30, 0x00, 0xC0, 0x00, 0x18, 0x00, 0xC0, 0x01, 0x1C, 0x00, 0x80, 0x03, 0x0F, 0x00, 0x00, 0x02, 0x03, // 199
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0xFF, 0x3F, 0x00, 0xE0, 0xFF, 0x3F, 0x00, 0x60, 0x30, 0x30, 0x00, 0x60, 0x30, 0x30, 0x00, 0x62, 0x30, 0x30, 0x00, 0x66, 0x30, 0x30, 0x00, 0x6E, 0x30, 0x30, 0x00, 0x68, 0x30, 0x30, 0x00, 0x60, 0x30, 0x30, 0x00, 0x60, 0x30, 0x30, 0x00, 0x60, 0x30, 0x30, 0x00, 0x60, 0x30, 0x30, 0x00, 0x60, 0x00, 0x30, // 200
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0xFF, 0x3F, 0x00, 0xE0, 0xFF, 0x3F, 0x00, 0x60, 0x30, 0x30, 0x00, 0x60, 0x30, 0x30, 0x00, 0x60, 0x30, 0x30, 0x00, 0x68, 0x30, 0x30, 0x00, 0x6E, 0x30, 0x30, 0x00, 0x66, 0x30, 0x30, 0x00, 0x62, 0x30, 0x30, 0x00, 0x60, 0x30, 0x30, 0x00, 0x60, 0x30, 0x30, 0x00, 0x60, 0x30, 0x30, 0x00, 0x60, 0x00, 0x30, // 201
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0xFF, 0x3F, 0x00, 0xE0, 0xFF, 0x3F, 0x00, 0x60, 0x30, 0x30, 0x00, 0x60, 0x30, 0x30, 0x00, 0x68, 0x30, 0x30, 0x00, 0x6C, 0x30, 0x30, 0x00, 0x66, 0x30, 0x30, 0x00, 0x66, 0x30, 0x30, 0x00, 0x6C, 0x30, 0x30, 0x00, 0x68, 0x30, 0x30, 0x00, 0x60, 0x30, 0x30, 0x00, 0x60, 0x30, 0x30, 0x00, 0x60, 0x00, 0x30, // 202
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0xFF, 0x3F, 0x00, 0xE0, 0xFF, 0x3F, 0x00, 0x60, 0x30, 0x30, 0x00, 0x60, 0x30, 0x30, 0x00, 0x6C, 0x30, 0x30, 0x00, 0x6C, 0x30, 0x30, 0x00, 0x60, 0x30, 0x30, 0x00, 0x60, 0x30, 0x30, 0x00, 0x6C, 0x30, 0x30, 0x00, 0x6C, 0x30, 0x30, 0x00, 0x60, 0x30, 0x30, 0x00, 0x60, 0x30, 0x30, 0x00, 0x60, 0x00, 0x30, // 203
+ 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0xE6, 0xFF, 0x3F, 0x00, 0xEE, 0xFF, 0x3F, 0x00, 0x08, // 204
+ 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0xEE, 0xFF, 0x3F, 0x00, 0xE6, 0xFF, 0x3F, 0x00, 0x02, // 205
+ 0x08, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0xE6, 0xFF, 0x3F, 0x00, 0xE6, 0xFF, 0x3F, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x08, // 206
+ 0x0C, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0xE0, 0xFF, 0x3F, 0x00, 0xE0, 0xFF, 0x3F, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x0C, // 207
+ 0x00, 0x30, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0xE0, 0xFF, 0x3F, 0x00, 0xE0, 0xFF, 0x3F, 0x00, 0x60, 0x30, 0x30, 0x00, 0x60, 0x30, 0x30, 0x00, 0x60, 0x30, 0x30, 0x00, 0x60, 0x30, 0x30, 0x00, 0x60, 0x30, 0x30, 0x00, 0x60, 0x00, 0x30, 0x00, 0x60, 0x00, 0x30, 0x00, 0xE0, 0x00, 0x18, 0x00, 0xC0, 0x01, 0x1C, 0x00, 0x80, 0x03, 0x0E, 0x00, 0x00, 0xFF, 0x07, 0x00, 0x00, 0xFC, 0x01, // 208
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0xFF, 0x3F, 0x00, 0xE0, 0xFF, 0x3F, 0x00, 0xC0, 0x01, 0x00, 0x00, 0x8C, 0x03, 0x00, 0x00, 0x0E, 0x0E, 0x00, 0x00, 0x06, 0x3C, 0x00, 0x00, 0x06, 0x70, 0x00, 0x00, 0x0C, 0xE0, 0x01, 0x00, 0x0C, 0x80, 0x03, 0x00, 0x0E, 0x00, 0x0F, 0x00, 0x06, 0x00, 0x1C, 0x00, 0xE0, 0xFF, 0x3F, 0x00, 0xE0, 0xFF, 0x3F, // 209
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 0x01, 0x00, 0x00, 0xFF, 0x07, 0x00, 0x80, 0x07, 0x0F, 0x00, 0xC0, 0x01, 0x1C, 0x00, 0xC0, 0x00, 0x18, 0x00, 0xE0, 0x00, 0x38, 0x00, 0x62, 0x00, 0x30, 0x00, 0x66, 0x00, 0x30, 0x00, 0x6E, 0x00, 0x30, 0x00, 0x68, 0x00, 0x30, 0x00, 0x60, 0x00, 0x30, 0x00, 0xE0, 0x00, 0x38, 0x00, 0xC0, 0x00, 0x18, 0x00, 0xC0, 0x01, 0x1C, 0x00, 0x80, 0x07, 0x0F, 0x00, 0x00, 0xFF, 0x07, 0x00, 0x00, 0xFC, 0x01, // 210
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 0x01, 0x00, 0x00, 0xFF, 0x07, 0x00, 0x80, 0x07, 0x0F, 0x00, 0xC0, 0x01, 0x1C, 0x00, 0xC0, 0x00, 0x18, 0x00, 0xE0, 0x00, 0x38, 0x00, 0x60, 0x00, 0x30, 0x00, 0x68, 0x00, 0x30, 0x00, 0x6E, 0x00, 0x30, 0x00, 0x66, 0x00, 0x30, 0x00, 0x62, 0x00, 0x30, 0x00, 0xE0, 0x00, 0x38, 0x00, 0xC0, 0x00, 0x18, 0x00, 0xC0, 0x01, 0x1C, 0x00, 0x80, 0x07, 0x0F, 0x00, 0x00, 0xFF, 0x07, 0x00, 0x00, 0xFC, 0x01, // 211
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 0x01, 0x00, 0x00, 0xFF, 0x07, 0x00, 0x80, 0x07, 0x0F, 0x00, 0xC0, 0x01, 0x1C, 0x00, 0xC0, 0x00, 0x18, 0x00, 0xE0, 0x00, 0x38, 0x00, 0x68, 0x00, 0x30, 0x00, 0x6C, 0x00, 0x30, 0x00, 0x66, 0x00, 0x30, 0x00, 0x66, 0x00, 0x30, 0x00, 0x6C, 0x00, 0x30, 0x00, 0xE8, 0x00, 0x38, 0x00, 0xC0, 0x00, 0x18, 0x00, 0xC0, 0x01, 0x1C, 0x00, 0x80, 0x07, 0x0F, 0x00, 0x00, 0xFF, 0x07, 0x00, 0x00, 0xFC, 0x01, // 212
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 0x01, 0x00, 0x00, 0xFF, 0x07, 0x00, 0x80, 0x07, 0x0F, 0x00, 0xC0, 0x01, 0x1C, 0x00, 0xCC, 0x00, 0x18, 0x00, 0xEE, 0x00, 0x38, 0x00, 0x66, 0x00, 0x30, 0x00, 0x66, 0x00, 0x30, 0x00, 0x6C, 0x00, 0x30, 0x00, 0x6C, 0x00, 0x30, 0x00, 0x6E, 0x00, 0x30, 0x00, 0xE6, 0x00, 0x38, 0x00, 0xC0, 0x00, 0x18, 0x00, 0xC0, 0x01, 0x1C, 0x00, 0x80, 0x07, 0x0F, 0x00, 0x00, 0xFF, 0x07, 0x00, 0x00, 0xFC, 0x01, // 213
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 0x01, 0x00, 0x00, 0xFF, 0x07, 0x00, 0x80, 0x07, 0x0F, 0x00, 0xC0, 0x01, 0x1C, 0x00, 0xC0, 0x00, 0x18, 0x00, 0xE0, 0x00, 0x38, 0x00, 0x6C, 0x00, 0x30, 0x00, 0x6C, 0x00, 0x30, 0x00, 0x60, 0x00, 0x30, 0x00, 0x60, 0x00, 0x30, 0x00, 0x6C, 0x00, 0x30, 0x00, 0xEC, 0x00, 0x38, 0x00, 0xC0, 0x00, 0x18, 0x00, 0xC0, 0x01, 0x1C, 0x00, 0x80, 0x07, 0x0F, 0x00, 0x00, 0xFF, 0x07, 0x00, 0x00, 0xFC, 0x01, // 214
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x03, 0x00, 0x00, 0x8E, 0x03, 0x00, 0x00, 0xDC, 0x01, 0x00, 0x00, 0xF8, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0xF8, 0x00, 0x00, 0x00, 0xDC, 0x01, 0x00, 0x00, 0x8E, 0x03, 0x00, 0x00, 0x06, 0x03, // 215
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 0x21, 0x00, 0x00, 0xFF, 0x77, 0x00, 0x80, 0x07, 0x3F, 0x00, 0xC0, 0x01, 0x1E, 0x00, 0xC0, 0x00, 0x1F, 0x00, 0xE0, 0x80, 0x3B, 0x00, 0x60, 0xC0, 0x31, 0x00, 0x60, 0xE0, 0x30, 0x00, 0x60, 0x70, 0x30, 0x00, 0x60, 0x38, 0x30, 0x00, 0x60, 0x1C, 0x30, 0x00, 0xE0, 0x0E, 0x38, 0x00, 0xC0, 0x07, 0x18, 0x00, 0xC0, 0x03, 0x1C, 0x00, 0xE0, 0x07, 0x0F, 0x00, 0x70, 0xFF, 0x07, 0x00, 0x20, 0xFC, 0x01, // 216
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0xFF, 0x03, 0x00, 0xE0, 0xFF, 0x0F, 0x00, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x00, 0x38, 0x00, 0x02, 0x00, 0x30, 0x00, 0x06, 0x00, 0x30, 0x00, 0x0E, 0x00, 0x30, 0x00, 0x08, 0x00, 0x30, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x1C, 0x00, 0xE0, 0xFF, 0x0F, 0x00, 0xE0, 0xFF, 0x03, // 217
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0xFF, 0x03, 0x00, 0xE0, 0xFF, 0x0F, 0x00, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x30, 0x00, 0x08, 0x00, 0x30, 0x00, 0x0E, 0x00, 0x30, 0x00, 0x06, 0x00, 0x30, 0x00, 0x02, 0x00, 0x30, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x1C, 0x00, 0xE0, 0xFF, 0x0F, 0x00, 0xE0, 0xFF, 0x03, // 218
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0xFF, 0x03, 0x00, 0xE0, 0xFF, 0x0F, 0x00, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x00, 0x38, 0x00, 0x08, 0x00, 0x30, 0x00, 0x0C, 0x00, 0x30, 0x00, 0x06, 0x00, 0x30, 0x00, 0x06, 0x00, 0x30, 0x00, 0x0C, 0x00, 0x30, 0x00, 0x08, 0x00, 0x38, 0x00, 0x00, 0x00, 0x1C, 0x00, 0xE0, 0xFF, 0x0F, 0x00, 0xE0, 0xFF, 0x03, // 219
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0xFF, 0x03, 0x00, 0xE0, 0xFF, 0x0F, 0x00, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x00, 0x38, 0x00, 0x0C, 0x00, 0x30, 0x00, 0x0C, 0x00, 0x30, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x30, 0x00, 0x0C, 0x00, 0x30, 0x00, 0x0C, 0x00, 0x38, 0x00, 0x00, 0x00, 0x1C, 0x00, 0xE0, 0xFF, 0x0F, 0x00, 0xE0, 0xFF, 0x03, // 220
+ 0x20, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0xC0, 0x01, 0x00, 0x00, 0x80, 0x03, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x1E, 0x00, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x08, 0xF0, 0x3F, 0x00, 0x0E, 0xF0, 0x3F, 0x00, 0x06, 0x3C, 0x00, 0x00, 0x02, 0x1E, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0xE0, 0x01, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x20, // 221
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0xFF, 0x3F, 0x00, 0xE0, 0xFF, 0x3F, 0x00, 0x00, 0x03, 0x06, 0x00, 0x00, 0x03, 0x06, 0x00, 0x00, 0x03, 0x06, 0x00, 0x00, 0x03, 0x06, 0x00, 0x00, 0x03, 0x06, 0x00, 0x00, 0x03, 0x06, 0x00, 0x00, 0x03, 0x06, 0x00, 0x00, 0x03, 0x07, 0x00, 0x00, 0x86, 0x03, 0x00, 0x00, 0xFE, 0x01, 0x00, 0x00, 0xF8, // 222
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xFF, 0x3F, 0x00, 0xC0, 0xFF, 0x3F, 0x00, 0xC0, 0x00, 0x00, 0x00, 0x60, 0x00, 0x08, 0x00, 0x60, 0x00, 0x1C, 0x00, 0x60, 0x00, 0x38, 0x00, 0xE0, 0x78, 0x30, 0x00, 0xC0, 0x7F, 0x30, 0x00, 0x80, 0xC7, 0x30, 0x00, 0x00, 0x80, 0x39, 0x00, 0x00, 0x80, 0x1F, 0x00, 0x00, 0x00, 0x0F, // 223
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x0E, 0x00, 0x00, 0x1C, 0x1F, 0x00, 0x00, 0x8C, 0x39, 0x00, 0x20, 0x86, 0x31, 0x00, 0x60, 0x86, 0x31, 0x00, 0xE0, 0xC6, 0x30, 0x00, 0x80, 0xC6, 0x18, 0x00, 0x00, 0xCE, 0x0C, 0x00, 0x00, 0xFC, 0x1F, 0x00, 0x00, 0xF8, 0x3F, 0x00, 0x00, 0x00, 0x20, // 224
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x0E, 0x00, 0x00, 0x1C, 0x1F, 0x00, 0x00, 0x8C, 0x39, 0x00, 0x00, 0x86, 0x31, 0x00, 0x80, 0x86, 0x31, 0x00, 0xE0, 0xC6, 0x30, 0x00, 0x60, 0xC6, 0x18, 0x00, 0x20, 0xCE, 0x0C, 0x00, 0x00, 0xFC, 0x1F, 0x00, 0x00, 0xF8, 0x3F, 0x00, 0x00, 0x00, 0x20, // 225
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x0E, 0x00, 0x00, 0x1C, 0x1F, 0x00, 0x80, 0x8C, 0x39, 0x00, 0xC0, 0x86, 0x31, 0x00, 0x60, 0x86, 0x31, 0x00, 0x60, 0xC6, 0x30, 0x00, 0xC0, 0xC6, 0x18, 0x00, 0x80, 0xCE, 0x0C, 0x00, 0x00, 0xFC, 0x1F, 0x00, 0x00, 0xF8, 0x3F, 0x00, 0x00, 0x00, 0x20, // 226
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x0E, 0x00, 0xC0, 0x1C, 0x1F, 0x00, 0xE0, 0x8C, 0x39, 0x00, 0x60, 0x86, 0x31, 0x00, 0x60, 0x86, 0x31, 0x00, 0xC0, 0xC6, 0x30, 0x00, 0xC0, 0xC6, 0x18, 0x00, 0xE0, 0xCE, 0x0C, 0x00, 0x60, 0xFC, 0x1F, 0x00, 0x00, 0xF8, 0x3F, 0x00, 0x00, 0x00, 0x20, // 227
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x0E, 0x00, 0x00, 0x1C, 0x1F, 0x00, 0xC0, 0x8C, 0x39, 0x00, 0xC0, 0x86, 0x31, 0x00, 0x00, 0x86, 0x31, 0x00, 0x00, 0xC6, 0x30, 0x00, 0xC0, 0xC6, 0x18, 0x00, 0xC0, 0xCE, 0x0C, 0x00, 0x00, 0xFC, 0x1F, 0x00, 0x00, 0xF8, 0x3F, 0x00, 0x00, 0x00, 0x20, // 228
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x0E, 0x00, 0x00, 0x1C, 0x1F, 0x00, 0x00, 0x8C, 0x39, 0x00, 0x70, 0x86, 0x31, 0x00, 0x88, 0x86, 0x31, 0x00, 0x88, 0xC6, 0x30, 0x00, 0x88, 0xC6, 0x18, 0x00, 0x70, 0xCE, 0x0C, 0x00, 0x00, 0xFC, 0x1F, 0x00, 0x00, 0xF8, 0x3F, 0x00, 0x00, 0x00, 0x20, // 229
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x0F, 0x00, 0x00, 0x9C, 0x1F, 0x00, 0x00, 0xCC, 0x39, 0x00, 0x00, 0xC6, 0x30, 0x00, 0x00, 0xC6, 0x30, 0x00, 0x00, 0xC6, 0x30, 0x00, 0x00, 0xC6, 0x30, 0x00, 0x00, 0x66, 0x18, 0x00, 0x00, 0x6E, 0x1C, 0x00, 0x00, 0xFC, 0x0F, 0x00, 0x00, 0xFC, 0x1F, 0x00, 0x00, 0xCC, 0x1C, 0x00, 0x00, 0xCE, 0x38, 0x00, 0x00, 0xC6, 0x30, 0x00, 0x00, 0xC6, 0x30, 0x00, 0x00, 0xC6, 0x30, 0x00, 0x00, 0xC6, 0x30, 0x00, 0x00, 0xCC, 0x18, 0x00, 0x00, 0xF8, 0x0C, 0x00, 0x00, 0xE0, 0x04, // 230
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x07, 0x00, 0x00, 0xF8, 0x0F, 0x00, 0x00, 0x1C, 0x1C, 0x00, 0x00, 0x0E, 0x38, 0x02, 0x00, 0x06, 0x30, 0x02, 0x00, 0x06, 0xF0, 0x02, 0x00, 0x06, 0xB0, 0x03, 0x00, 0x0E, 0x38, 0x01, 0x00, 0x1C, 0x1C, 0x00, 0x00, 0x18, 0x0C, // 231
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0x07, 0x00, 0x00, 0xF8, 0x0F, 0x00, 0x00, 0xDC, 0x1C, 0x00, 0x20, 0xCE, 0x38, 0x00, 0x60, 0xC6, 0x30, 0x00, 0xE0, 0xC6, 0x30, 0x00, 0x80, 0xC6, 0x30, 0x00, 0x00, 0xCE, 0x38, 0x00, 0x00, 0xDC, 0x18, 0x00, 0x00, 0xF8, 0x0C, 0x00, 0x00, 0xF0, 0x04, // 232
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0x07, 0x00, 0x00, 0xF8, 0x0F, 0x00, 0x00, 0xDC, 0x1C, 0x00, 0x00, 0xCE, 0x38, 0x00, 0x80, 0xC6, 0x30, 0x00, 0xE0, 0xC6, 0x30, 0x00, 0x60, 0xC6, 0x30, 0x00, 0x20, 0xCE, 0x38, 0x00, 0x00, 0xDC, 0x18, 0x00, 0x00, 0xF8, 0x0C, 0x00, 0x00, 0xF0, 0x04, // 233
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0x07, 0x00, 0x00, 0xF8, 0x0F, 0x00, 0x00, 0xDC, 0x1C, 0x00, 0x80, 0xCE, 0x38, 0x00, 0xC0, 0xC6, 0x30, 0x00, 0x60, 0xC6, 0x30, 0x00, 0x60, 0xC6, 0x30, 0x00, 0xC0, 0xCE, 0x38, 0x00, 0x80, 0xDC, 0x18, 0x00, 0x00, 0xF8, 0x0C, 0x00, 0x00, 0xF0, 0x04, // 234
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0x07, 0x00, 0x00, 0xF8, 0x0F, 0x00, 0x00, 0xDC, 0x1C, 0x00, 0xC0, 0xCE, 0x38, 0x00, 0xC0, 0xC6, 0x30, 0x00, 0x00, 0xC6, 0x30, 0x00, 0x00, 0xC6, 0x30, 0x00, 0xC0, 0xCE, 0x38, 0x00, 0xC0, 0xDC, 0x18, 0x00, 0x00, 0xF8, 0x0C, 0x00, 0x00, 0xF0, 0x04, // 235
+ 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x60, 0xFE, 0x3F, 0x00, 0xE0, 0xFE, 0x3F, 0x00, 0x80, // 236
+ 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0xE0, 0xFE, 0x3F, 0x00, 0x60, 0xFE, 0x3F, 0x00, 0x20, // 237
+ 0x80, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0x60, 0xFE, 0x3F, 0x00, 0x60, 0xFE, 0x3F, 0x00, 0xC0, 0x00, 0x00, 0x00, 0x80, // 238
+ 0xC0, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0x00, 0xFE, 0x3F, 0x00, 0x00, 0xFE, 0x3F, 0x00, 0xC0, 0x00, 0x00, 0x00, 0xC0, // 239
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x07, 0x00, 0x00, 0xF8, 0x0F, 0x00, 0x00, 0x1D, 0x1C, 0x00, 0xA0, 0x0F, 0x38, 0x00, 0xA0, 0x06, 0x30, 0x00, 0xE0, 0x06, 0x30, 0x00, 0xC0, 0x06, 0x30, 0x00, 0xC0, 0x0F, 0x38, 0x00, 0x20, 0x1F, 0x1C, 0x00, 0x00, 0xFC, 0x0F, 0x00, 0x00, 0xE0, 0x07, // 240
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0x3F, 0x00, 0xC0, 0xFE, 0x3F, 0x00, 0xE0, 0x18, 0x00, 0x00, 0x60, 0x0C, 0x00, 0x00, 0x60, 0x06, 0x00, 0x00, 0xC0, 0x06, 0x00, 0x00, 0xC0, 0x06, 0x00, 0x00, 0xE0, 0x0E, 0x00, 0x00, 0x60, 0xFC, 0x3F, 0x00, 0x00, 0xF8, 0x3F, // 241
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x07, 0x00, 0x00, 0xF8, 0x0F, 0x00, 0x00, 0x1C, 0x1C, 0x00, 0x20, 0x0E, 0x38, 0x00, 0x60, 0x06, 0x30, 0x00, 0xE0, 0x06, 0x30, 0x00, 0x80, 0x06, 0x30, 0x00, 0x00, 0x0E, 0x38, 0x00, 0x00, 0x1C, 0x1C, 0x00, 0x00, 0xF8, 0x0F, 0x00, 0x00, 0xF0, 0x07, // 242
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x07, 0x00, 0x00, 0xF8, 0x0F, 0x00, 0x00, 0x1C, 0x1C, 0x00, 0x00, 0x0E, 0x38, 0x00, 0x80, 0x06, 0x30, 0x00, 0xE0, 0x06, 0x30, 0x00, 0x60, 0x06, 0x30, 0x00, 0x20, 0x0E, 0x38, 0x00, 0x00, 0x1C, 0x1C, 0x00, 0x00, 0xF8, 0x0F, 0x00, 0x00, 0xF0, 0x07, // 243
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x07, 0x00, 0x00, 0xF8, 0x0F, 0x00, 0x00, 0x1C, 0x1C, 0x00, 0x80, 0x0E, 0x38, 0x00, 0xC0, 0x06, 0x30, 0x00, 0x60, 0x06, 0x30, 0x00, 0x60, 0x06, 0x30, 0x00, 0xC0, 0x0E, 0x38, 0x00, 0x80, 0x1C, 0x1C, 0x00, 0x00, 0xF8, 0x0F, 0x00, 0x00, 0xF0, 0x07, // 244
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x07, 0x00, 0x00, 0xF8, 0x0F, 0x00, 0xC0, 0x1C, 0x1C, 0x00, 0xE0, 0x0E, 0x38, 0x00, 0x60, 0x06, 0x30, 0x00, 0x60, 0x06, 0x30, 0x00, 0xC0, 0x06, 0x30, 0x00, 0xC0, 0x0E, 0x38, 0x00, 0xE0, 0x1C, 0x1C, 0x00, 0x60, 0xF8, 0x0F, 0x00, 0x00, 0xF0, 0x07, // 245
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x07, 0x00, 0x00, 0xF8, 0x0F, 0x00, 0x00, 0x1C, 0x1C, 0x00, 0xC0, 0x0E, 0x38, 0x00, 0xC0, 0x06, 0x30, 0x00, 0x00, 0x06, 0x30, 0x00, 0x00, 0x06, 0x30, 0x00, 0xC0, 0x0E, 0x38, 0x00, 0xC0, 0x1C, 0x1C, 0x00, 0x00, 0xF8, 0x0F, 0x00, 0x00, 0xF0, 0x07, // 246
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0xB6, 0x01, 0x00, 0x00, 0xB6, 0x01, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x30, // 247
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x67, 0x00, 0x00, 0xF8, 0x7F, 0x00, 0x00, 0x1C, 0x1C, 0x00, 0x00, 0x0E, 0x3F, 0x00, 0x00, 0x86, 0x33, 0x00, 0x00, 0xE6, 0x31, 0x00, 0x00, 0x76, 0x30, 0x00, 0x00, 0x3E, 0x38, 0x00, 0x00, 0x1C, 0x1C, 0x00, 0x00, 0xFF, 0x0F, 0x00, 0x00, 0xF3, 0x07, // 248
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0x0F, 0x00, 0x00, 0xFE, 0x1F, 0x00, 0x20, 0x00, 0x38, 0x00, 0x60, 0x00, 0x30, 0x00, 0xE0, 0x00, 0x30, 0x00, 0x80, 0x00, 0x30, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0xFE, 0x3F, 0x00, 0x00, 0xFE, 0x3F, // 249
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0x0F, 0x00, 0x00, 0xFE, 0x1F, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x30, 0x00, 0x80, 0x00, 0x30, 0x00, 0xE0, 0x00, 0x30, 0x00, 0x60, 0x00, 0x18, 0x00, 0x20, 0x00, 0x0C, 0x00, 0x00, 0xFE, 0x3F, 0x00, 0x00, 0xFE, 0x3F, // 250
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0x0F, 0x00, 0x00, 0xFE, 0x1F, 0x00, 0x80, 0x00, 0x38, 0x00, 0xC0, 0x00, 0x30, 0x00, 0x60, 0x00, 0x30, 0x00, 0x60, 0x00, 0x30, 0x00, 0xC0, 0x00, 0x18, 0x00, 0x80, 0x00, 0x0C, 0x00, 0x00, 0xFE, 0x3F, 0x00, 0x00, 0xFE, 0x3F, // 251
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0x0F, 0x00, 0x00, 0xFE, 0x1F, 0x00, 0xC0, 0x00, 0x38, 0x00, 0xC0, 0x00, 0x30, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x30, 0x00, 0xC0, 0x00, 0x18, 0x00, 0xC0, 0x00, 0x0C, 0x00, 0x00, 0xFE, 0x3F, 0x00, 0x00, 0xFE, 0x3F, // 252
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x7E, 0x00, 0x06, 0x00, 0xF0, 0x01, 0x06, 0x00, 0x80, 0x0F, 0x07, 0x80, 0x00, 0xFE, 0x03, 0xE0, 0x00, 0xFC, 0x00, 0x60, 0xC0, 0x1F, 0x00, 0x20, 0xF8, 0x03, 0x00, 0x00, 0x3E, 0x00, 0x00, 0x00, 0x06, // 253
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0xFF, 0xFF, 0x07, 0xE0, 0xFF, 0xFF, 0x07, 0x00, 0x1C, 0x18, 0x00, 0x00, 0x06, 0x30, 0x00, 0x00, 0x06, 0x30, 0x00, 0x00, 0x06, 0x30, 0x00, 0x00, 0x0E, 0x38, 0x00, 0x00, 0x1C, 0x1C, 0x00, 0x00, 0xF8, 0x0F, 0x00, 0x00, 0xF0, 0x03, // 254
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x7E, 0x00, 0x06, 0xC0, 0xF0, 0x01, 0x06, 0xC0, 0x80, 0x0F, 0x07, 0x00, 0x00, 0xFE, 0x03, 0x00, 0x00, 0xFC, 0x00, 0xC0, 0xC0, 0x1F, 0x00, 0xC0, 0xF8, 0x03, 0x00, 0x00, 0x3E, 0x00, 0x00, 0x00, 0x06, // 255
};
\ No newline at end of file
diff --git a/src/graphics/niche/Drivers/Backlight/LatchingBacklight.cpp b/src/graphics/niche/Drivers/Backlight/LatchingBacklight.cpp
new file mode 100644
index 000000000..7e4f0b709
--- /dev/null
+++ b/src/graphics/niche/Drivers/Backlight/LatchingBacklight.cpp
@@ -0,0 +1,110 @@
+#ifdef MESHTASTIC_INCLUDE_NICHE_GRAPHICS
+
+#include "./LatchingBacklight.h"
+
+#include "assert.h"
+
+#include "sleep.h"
+
+using namespace NicheGraphics::Drivers;
+
+// Private constructor
+// Called by getInstance
+LatchingBacklight::LatchingBacklight()
+{
+ // Attach the deep sleep callback
+ deepSleepObserver.observe(¬ifyDeepSleep);
+}
+
+// Get access to (or create) the singleton instance of this class
+LatchingBacklight *LatchingBacklight::getInstance()
+{
+ // Instantiate the class the first time this method is called
+ static LatchingBacklight *const singletonInstance = new LatchingBacklight;
+
+ return singletonInstance;
+}
+
+// Which pin controls the backlight?
+// Is the light active HIGH (default) or active LOW?
+void LatchingBacklight::setPin(uint8_t pin, bool activeWhen)
+{
+ this->pin = pin;
+ this->logicActive = activeWhen;
+
+ pinMode(pin, OUTPUT);
+ off(); // Explicit off seem required by T-Echo?
+}
+
+// Called when device is shutting down
+// Ensures the backlight is off
+int LatchingBacklight::beforeDeepSleep(void *unused)
+{
+ // We shouldn't need to guard the block like this
+ // Contingency for:
+ // - settings corruption: settings.optionalMenuItems.backlight guards backlight code in MenuApplet
+ // - improper use in the future
+ if (pin != (uint8_t)-1) {
+ off();
+ pinMode(pin, INPUT); // High impedence - unnecessary?
+ } else
+ LOG_WARN("LatchingBacklight instantiated, but pin not set");
+ return 0; // Continue with deep sleep
+}
+
+// Turn the backlight on *temporarily*
+// This should be used for momentary illumination, such as while a button is held
+// The effect on the backlight is the same; peek and latch are separated to simplify short vs long press button handling
+void LatchingBacklight::peek()
+{
+ assert(pin != (uint8_t)-1);
+ digitalWrite(pin, logicActive); // On
+ on = true;
+ latched = false;
+}
+
+// Turn the backlight on, and keep it on
+// This should be used when the backlight should remain active, even after user input ends
+// e.g. when enabled via the menu
+// The effect on the backlight is the same; peek and latch are separated to simplify short vs long press button handling
+void LatchingBacklight::latch()
+{
+ assert(pin != (uint8_t)-1);
+
+ // Blink if moving from peek to latch
+ // Indicates to user that the transition has taken place
+ if (on && !latched) {
+ digitalWrite(pin, !logicActive); // Off
+ delay(25);
+ digitalWrite(pin, logicActive); // On
+ delay(25);
+ digitalWrite(pin, !logicActive); // Off
+ delay(25);
+ }
+
+ digitalWrite(pin, logicActive); // On
+ on = true;
+ latched = true;
+}
+
+// Turn the backlight off
+// Suitable for ending both peek and latch
+void LatchingBacklight::off()
+{
+ assert(pin != (uint8_t)-1);
+ digitalWrite(pin, !logicActive); // Off
+ on = false;
+ latched = false;
+}
+
+bool LatchingBacklight::isOn()
+{
+ return on;
+}
+
+bool LatchingBacklight::isLatched()
+{
+ return latched;
+}
+
+#endif
diff --git a/src/graphics/niche/Drivers/Backlight/LatchingBacklight.h b/src/graphics/niche/Drivers/Backlight/LatchingBacklight.h
new file mode 100644
index 000000000..0097cae4c
--- /dev/null
+++ b/src/graphics/niche/Drivers/Backlight/LatchingBacklight.h
@@ -0,0 +1,50 @@
+/*
+
+ Singleton class
+ On-demand control of a display's backlight, connected to a GPIO
+ Initial use case is control of T-Echo's frontlight, via the capacitive touch button
+
+ - momentary on
+ - latched on
+
+*/
+
+#pragma once
+
+#include "configuration.h"
+
+#include "Observer.h"
+
+namespace NicheGraphics::Drivers
+{
+
+class LatchingBacklight
+{
+ public:
+ static LatchingBacklight *getInstance(); // Create or get the singleton instance
+ void setPin(uint8_t pin, bool activeWhen = HIGH);
+
+ int beforeDeepSleep(void *unused); // Callback for auto-shutoff
+
+ void peek(); // Backlight on temporarily, e.g. while button held
+ void latch(); // Backlight on permanently, e.g. toggled via menu
+ void off(); // Backlight off. Suitable for both peek and latch
+
+ bool isOn(); // Either peek or latch
+ bool isLatched();
+
+ private:
+ LatchingBacklight(); // Constructor made private: force use of getInstance
+
+ // Get notified when the system is shutting down
+ CallbackObserver deepSleepObserver =
+ CallbackObserver(this, &LatchingBacklight::beforeDeepSleep);
+
+ uint8_t pin = (uint8_t)-1;
+ bool logicActive = HIGH; // Is light active HIGH or active LOW
+
+ bool on = false; // Is light on (either peek or latched)
+ bool latched = false; // Is light latched on
+};
+
+} // namespace NicheGraphics::Drivers
\ No newline at end of file
diff --git a/src/graphics/niche/Drivers/EInk/DEPG0154BNS800.cpp b/src/graphics/niche/Drivers/EInk/DEPG0154BNS800.cpp
new file mode 100644
index 000000000..b8715ed1d
--- /dev/null
+++ b/src/graphics/niche/Drivers/EInk/DEPG0154BNS800.cpp
@@ -0,0 +1 @@
+#include "./DEPG0154BNS800.h"
\ No newline at end of file
diff --git a/src/graphics/niche/Drivers/EInk/DEPG0154BNS800.h b/src/graphics/niche/Drivers/EInk/DEPG0154BNS800.h
new file mode 100644
index 000000000..62d42ef57
--- /dev/null
+++ b/src/graphics/niche/Drivers/EInk/DEPG0154BNS800.h
@@ -0,0 +1,34 @@
+/*
+
+E-Ink display driver
+ - DEPG0154BNS800
+ - Manufacturer: DKE
+ - Size: 1.54 inch
+ - Resolution: 152px x 152px
+ - Flex connector marking: FPC7525
+
+*/
+
+#pragma once
+
+#ifdef MESHTASTIC_INCLUDE_NICHE_GRAPHICS
+#include "configuration.h"
+
+#include "./SSD16XX.h"
+
+namespace NicheGraphics::Drivers
+{
+class DEPG0154BNS800 : public SSD16XX
+{
+ // Display properties
+ private:
+ static constexpr uint32_t width = 152;
+ static constexpr uint32_t height = 152;
+ static constexpr UpdateTypes supported = (UpdateTypes)(FULL);
+
+ public:
+ DEPG0154BNS800() : SSD16XX(width, height, supported, 1) {} // Note: left edge of this display is offset by 1 byte
+};
+
+} // namespace NicheGraphics::Drivers
+#endif // MESHTASTIC_INCLUDE_NICHE_GRAPHICS
\ No newline at end of file
diff --git a/src/graphics/niche/Drivers/EInk/DEPG0290BNS800.cpp b/src/graphics/niche/Drivers/EInk/DEPG0290BNS800.cpp
new file mode 100644
index 000000000..5f3a05670
--- /dev/null
+++ b/src/graphics/niche/Drivers/EInk/DEPG0290BNS800.cpp
@@ -0,0 +1,120 @@
+#include "./DEPG0290BNS800.h"
+
+#ifdef MESHTASTIC_INCLUDE_NICHE_GRAPHICS
+
+using namespace NicheGraphics::Drivers;
+
+// Describes the operation performed when a "fast refresh" is performed
+// Source: custom, with DEPG0150BNS810 as a reference
+static const uint8_t LUT_FAST[] = {
+ // 1 2 3 4
+ 0x40, 0x00, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // B2B (Existing black pixels)
+ 0x00, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // B2W (New white pixels)
+ 0x00, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // W2B (New black pixels)
+ 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // W2W (Existing white pixels)
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // VCOM
+
+ 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 1. Tap existing black pixels back into place
+ 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 2. Move new pixels
+ 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 3. New pixels, and also existing black pixels
+ 0x02, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, // 4. All pixels, then cooldown
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
+
+ 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x00, 0x00, 0x00,
+};
+
+// How strongly the pixels are pulled and pushed
+void DEPG0290BNS800::configVoltages()
+{
+ switch (updateType) {
+ case FAST:
+ // Listed as "typical" in datasheet
+ sendCommand(0x04);
+ sendData(0x41); // VSH1 15V
+ sendData(0x00); // VSH2 NA
+ sendData(0x32); // VSL -15V
+ break;
+
+ case FULL:
+ default:
+ // From OTP memory
+ break;
+ }
+}
+
+// Load settings about how the pixels are moved from old state to new state during a refresh
+// - manually specified,
+// - or with stored values from displays OTP memory
+void DEPG0290BNS800::configWaveform()
+{
+ switch (updateType) {
+ case FAST:
+ sendCommand(0x3C); // Border waveform:
+ sendData(0x60); // Actively hold screen border during update
+
+ sendCommand(0x32); // Write LUT register from MCU:
+ sendData(LUT_FAST, sizeof(LUT_FAST)); // (describes operation for a FAST refresh)
+ break;
+
+ case FULL:
+ default:
+ // From OTP memory
+ break;
+ }
+}
+
+// Describes the sequence of events performed by the displays controller IC during a refresh
+// Includes "power up", "load settings from memory", "update the pixels", etc
+void DEPG0290BNS800::configUpdateSequence()
+{
+ switch (updateType) {
+ case FAST:
+ sendCommand(0x22); // Set "update sequence"
+ sendData(0xCF); // Differential, use manually loaded waveform
+ break;
+
+ case FULL:
+ default:
+ sendCommand(0x22); // Set "update sequence"
+ sendData(0xF7); // Non-differential, load waveform from OTP
+ break;
+ }
+}
+
+// Once the refresh operation has been started,
+// begin periodically polling the display to check for completion, using the normal Meshtastic threading code
+// Only used when refresh is "async"
+void DEPG0290BNS800::detachFromUpdate()
+{
+ switch (updateType) {
+ case FAST:
+ return beginPolling(50, 450); // At least 450ms for fast refresh
+ case FULL:
+ default:
+ return beginPolling(100, 3000); // At least 3 seconds for full refresh
+ }
+}
+
+// For this display, we do not need to re-write the new image.
+// We're overriding SSD16XX::finalizeUpdate to make this small optimization.
+// The display does also work just fine with the generic SSD16XX method, though.
+void DEPG0290BNS800::finalizeUpdate()
+{
+ // Put a copy of the image into the "old memory".
+ // Used with differential refreshes (e.g. FAST update), to determine which px need to move, and which can remain in place
+ // We need to keep the "old memory" up to date, because don't know whether next refresh will be FULL or FAST etc.
+ if (updateType != FULL) {
+ // writeNewImage(); // Not required for this display
+ writeOldImage();
+ sendCommand(0x7F); // Terminate image write without update
+ wait();
+ }
+}
+#endif // MESHTASTIC_INCLUDE_NICHE_GRAPHICS
\ No newline at end of file
diff --git a/src/graphics/niche/Drivers/EInk/DEPG0290BNS800.h b/src/graphics/niche/Drivers/EInk/DEPG0290BNS800.h
new file mode 100644
index 000000000..72062e0d6
--- /dev/null
+++ b/src/graphics/niche/Drivers/EInk/DEPG0290BNS800.h
@@ -0,0 +1,42 @@
+/*
+
+E-Ink display driver
+ - DEPG0290BNS800
+ - Manufacturer: DKE
+ - Size: 2.9 inch
+ - Resolution: 128px x 296px
+ - Flex connector marking: FPC-7519 rev.b
+
+*/
+
+#pragma once
+
+#ifdef MESHTASTIC_INCLUDE_NICHE_GRAPHICS
+
+#include "configuration.h"
+
+#include "./SSD16XX.h"
+
+namespace NicheGraphics::Drivers
+{
+class DEPG0290BNS800 : public SSD16XX
+{
+ // Display properties
+ private:
+ static constexpr uint32_t width = 128;
+ static constexpr uint32_t height = 296;
+ static constexpr UpdateTypes supported = (UpdateTypes)(FULL | FAST);
+
+ public:
+ DEPG0290BNS800() : SSD16XX(width, height, supported, 1) {} // Note: left edge of this display is offset by 1 byte
+
+ protected:
+ void configVoltages() override;
+ void configWaveform() override;
+ void configUpdateSequence() override;
+ void detachFromUpdate() override;
+ void finalizeUpdate() override; // Only overriden for a slight optimization
+};
+
+} // namespace NicheGraphics::Drivers
+#endif // MESHTASTIC_INCLUDE_NICHE_GRAPHICS
\ No newline at end of file
diff --git a/src/graphics/niche/Drivers/EInk/EInk.cpp b/src/graphics/niche/Drivers/EInk/EInk.cpp
new file mode 100644
index 000000000..0abe20bf9
--- /dev/null
+++ b/src/graphics/niche/Drivers/EInk/EInk.cpp
@@ -0,0 +1,70 @@
+#include "./EInk.h"
+
+#ifdef MESHTASTIC_INCLUDE_NICHE_GRAPHICS
+
+using namespace NicheGraphics::Drivers;
+
+// Separate from EInk::begin method, as derived class constructors can probably supply these parameters as constants
+EInk::EInk(uint16_t width, uint16_t height, UpdateTypes supported)
+ : concurrency::OSThread("E-Ink Driver"), width(width), height(height), supportedUpdateTypes(supported)
+{
+ OSThread::disable();
+}
+
+// Used by NicheGraphics implementations to check if a display supports a specific refresh operation.
+// Whether or the update type is supported is specified in the constructor
+bool EInk::supports(UpdateTypes type)
+{
+ // The EInkUpdateTypes enum assigns each type a unique bit. We are checking if that bit is set.
+ if (supportedUpdateTypes & type)
+ return true;
+ else
+ return false;
+}
+
+// Begins using the OSThread to detect when a display update is complete
+// This allows the refresh operation to run "asynchronously".
+// Rather than blocking execution waiting for the update to complete, we are periodically checking the hardware's BUSY pin
+// The expectedDuration argument allows us to delay the start of this checking, if we know "roughly" how long an update takes.
+// Potentially, a display without hardware BUSY could rely entirely on "expectedDuration",
+// provided its isUpdateDone() override always returns true.
+void EInk::beginPolling(uint32_t interval, uint32_t expectedDuration)
+{
+ updateRunning = true;
+ updateBegunAt = millis();
+ pollingInterval = interval;
+
+ // To minimize load, we can choose to delay polling for a few seconds, if we know roughly how long the update will take
+ // By default, expectedDuration is 0, and we'll start polling immediately
+ OSThread::setIntervalFromNow(expectedDuration);
+ OSThread::enabled = true;
+}
+
+// Meshtastic's pseudo-threading layer
+// We're using this as a timer, to periodically check if an update is complete
+// This is what allows us to update the display asynchronously
+int32_t EInk::runOnce()
+{
+ if (!isUpdateDone())
+ return pollingInterval; // Poll again in a few ms
+
+ // If update done:
+ finalizeUpdate(); // Any post-update code: power down panel hardware, hibernate, etc
+ updateRunning = false; // Change what we report via EInk::busy()
+ return disable(); // Stop polling
+}
+
+// Wait for an in progress update to complete before continuing
+// Run a normal (async) update first, *then* call await
+void EInk::await()
+{
+ // Stop our concurrency thread
+ OSThread::disable();
+
+ // Sit and block until the update is complete
+ while (updateRunning) {
+ runOnce();
+ yield();
+ }
+}
+#endif // MESHTASTIC_INCLUDE_NICHE_GRAPHICS
\ No newline at end of file
diff --git a/src/graphics/niche/Drivers/EInk/EInk.h b/src/graphics/niche/Drivers/EInk/EInk.h
new file mode 100644
index 000000000..1fbc25a14
--- /dev/null
+++ b/src/graphics/niche/Drivers/EInk/EInk.h
@@ -0,0 +1,56 @@
+/*
+
+ Base class for E-Ink display drivers
+
+*/
+
+#pragma once
+
+#ifdef MESHTASTIC_INCLUDE_NICHE_GRAPHICS
+#include "configuration.h"
+
+#include "concurrency/OSThread.h"
+#include
+
+namespace NicheGraphics::Drivers
+{
+
+class EInk : private concurrency::OSThread
+{
+ public:
+ // Different possible operations used to update an E-Ink display
+ // Some displays will not support all operations
+ // Each value needs a unique bit. In some cases, we might set more than one bit (e.g. EInk::supportedUpdateType)
+ enum UpdateTypes : uint8_t {
+ UNSPECIFIED = 0,
+ FULL = 1 << 0,
+ FAST = 1 << 1,
+ };
+
+ EInk(uint16_t width, uint16_t height, UpdateTypes supported);
+ virtual void begin(SPIClass *spi, uint8_t pin_dc, uint8_t pin_cs, uint8_t pin_busy, uint8_t pin_rst = -1) = 0;
+ virtual void update(uint8_t *imageData, UpdateTypes type) = 0; // Change the display image
+ void await(); // Wait for an in-progress update to complete before proceeding
+ bool supports(UpdateTypes type); // Can display perfom a certain update type
+ bool busy() { return updateRunning; } // Display able to update right now?
+
+ const uint16_t width; // Public so that NicheGraphics implementations can access. Safe because const.
+ const uint16_t height;
+
+ protected:
+ void beginPolling(uint32_t interval, uint32_t expectedDuration); // Begin checking repeatedly if update finished
+ virtual bool isUpdateDone() = 0; // Check once if update finished
+ virtual void finalizeUpdate() {} // Run any post-update code
+
+ private:
+ int32_t runOnce() override; // Repeated checking if update finished
+
+ const UpdateTypes supportedUpdateTypes; // Capabilities of a derived display class
+ bool updateRunning = false; // see EInk::busy()
+ uint32_t updateBegunAt; // For initial pause before polling for update completion
+ uint32_t pollingInterval; // How often to check if update complete (ms)
+};
+
+} // namespace NicheGraphics::Drivers
+
+#endif // MESHTASTIC_INCLUDE_NICHE_GRAPHICS
\ No newline at end of file
diff --git a/src/graphics/niche/Drivers/EInk/GDEY0154D67.cpp b/src/graphics/niche/Drivers/EInk/GDEY0154D67.cpp
new file mode 100644
index 000000000..bfc5ac681
--- /dev/null
+++ b/src/graphics/niche/Drivers/EInk/GDEY0154D67.cpp
@@ -0,0 +1,61 @@
+#include "./GDEY0154D67.h"
+
+#ifdef MESHTASTIC_INCLUDE_NICHE_GRAPHICS
+
+using namespace NicheGraphics::Drivers;
+
+// Map the display controller IC's output to the conected panel
+void GDEY0154D67::configScanning()
+{
+ // "Driver output control"
+ sendCommand(0x01);
+ sendData(0xC7);
+ sendData(0x00);
+ sendData(0x00);
+
+ // To-do: delete this method?
+ // Values set here might be redundant: C7, 00, 00 seems to be default
+}
+
+// Specify which information is used to control the sequence of voltages applied to move the pixels
+// - For this display, configUpdateSequence() specifies that a suitable LUT will be loaded from
+// the controller IC's OTP memory, when the update procedure begins.
+void GDEY0154D67::configWaveform()
+{
+ sendCommand(0x3C); // Border waveform:
+ sendData(0x05); // Screen border should follow LUT1 waveform (actively drive pixels white)
+
+ sendCommand(0x18); // Temperature sensor:
+ sendData(0x80); // Use internal temperature sensor to select an appropriate refresh waveform
+}
+
+void GDEY0154D67::configUpdateSequence()
+{
+ switch (updateType) {
+ case FAST:
+ sendCommand(0x22); // Set "update sequence"
+ sendData(0xFF); // Will load LUT from OTP memory, Display mode 2 "differential refresh"
+ break;
+
+ case FULL:
+ default:
+ sendCommand(0x22); // Set "update sequence"
+ sendData(0xF7); // Will load LUT from OTP memory
+ break;
+ }
+}
+
+// Once the refresh operation has been started,
+// begin periodically polling the display to check for completion, using the normal Meshtastic threading code
+// Only used when refresh is "async"
+void GDEY0154D67::detachFromUpdate()
+{
+ switch (updateType) {
+ case FAST:
+ return beginPolling(50, 500); // At least 500ms for fast refresh
+ case FULL:
+ default:
+ return beginPolling(100, 2000); // At least 2 seconds for full refresh
+ }
+}
+#endif // MESHTASTIC_INCLUDE_NICHE_GRAPHICS
\ No newline at end of file
diff --git a/src/graphics/niche/Drivers/EInk/GDEY0154D67.h b/src/graphics/niche/Drivers/EInk/GDEY0154D67.h
new file mode 100644
index 000000000..fc4d93d12
--- /dev/null
+++ b/src/graphics/niche/Drivers/EInk/GDEY0154D67.h
@@ -0,0 +1,42 @@
+/*
+
+E-Ink display driver
+ - GDEY0154D67
+ - Manufacturer: Goodisplay
+ - Size: 1.54 inch
+ - Resolution: 200px x 200px
+ - Flex connector marking: FPC-B001
+
+*/
+
+#pragma once
+
+#ifdef MESHTASTIC_INCLUDE_NICHE_GRAPHICS
+
+#include "configuration.h"
+
+#include "./SSD16XX.h"
+
+namespace NicheGraphics::Drivers
+{
+class GDEY0154D67 : public SSD16XX
+{
+ // Display properties
+ private:
+ static constexpr uint32_t width = 200;
+ static constexpr uint32_t height = 200;
+ static constexpr UpdateTypes supported = (UpdateTypes)(FULL | FAST);
+
+ public:
+ GDEY0154D67() : SSD16XX(width, height, supported) {}
+
+ protected:
+ virtual void configScanning() override;
+ virtual void configWaveform() override;
+ virtual void configUpdateSequence() override;
+ void detachFromUpdate() override;
+};
+
+} // namespace NicheGraphics::Drivers
+
+#endif // MESHTASTIC_INCLUDE_NICHE_GRAPHICS
\ No newline at end of file
diff --git a/src/graphics/niche/Drivers/EInk/LCMEN2R13EFC1.cpp b/src/graphics/niche/Drivers/EInk/LCMEN2R13EFC1.cpp
new file mode 100644
index 000000000..c54769fc2
--- /dev/null
+++ b/src/graphics/niche/Drivers/EInk/LCMEN2R13EFC1.cpp
@@ -0,0 +1,301 @@
+#include "./LCMEN2R13EFC1.h"
+
+#ifdef MESHTASTIC_INCLUDE_NICHE_GRAPHICS
+
+#include
+
+using namespace NicheGraphics::Drivers;
+
+// Look up table: fast refresh, common electrode
+static const uint8_t LUT_FAST_VCOMDC[] = {
+ 0x01, 0x06, 0x03, 0x02, 0x01, 0x01, 0x01, //
+ 0x01, 0x06, 0x02, 0x01, 0x01, 0x01, 0x01, //
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
+};
+
+// Look up table: fast refresh, pixels which remain white
+static const uint8_t LUT_FAST_WW[] = {
+ 0x01, 0x06, 0x03, 0x02, 0x81, 0x01, 0x01, //
+ 0x01, 0x06, 0x02, 0x01, 0x01, 0x01, 0x01, //
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
+};
+
+// Look up table: fast refresh, pixel which change from black to white
+static const uint8_t LUT_FAST_BW[] = {
+ 0x01, 0x86, 0x83, 0x82, 0x81, 0x01, 0x01, //
+ 0x01, 0x86, 0x82, 0x01, 0x01, 0x01, 0x01, //
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
+};
+
+// Look up table: fash refresh, pixels which change from white to black
+static const uint8_t LUT_FAST_WB[] = {
+ 0x01, 0x46, 0x42, 0x01, 0x01, 0x01, 0x01, //
+ 0x01, 0x46, 0x42, 0x01, 0x01, 0x01, 0x01, //
+ 0x01, 0x46, 0x43, 0x02, 0x01, 0x01, 0x01, //
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
+};
+
+// Look up table: fash refresh, pixels which remain black
+static const uint8_t LUT_FAST_BB[] = {
+ 0x01, 0x06, 0x03, 0x42, 0x41, 0x01, 0x01, //
+ 0x01, 0x06, 0x02, 0x01, 0x01, 0x01, 0x01, //
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
+};
+
+LCMEN213EFC1::LCMEN213EFC1() : EInk(width, height, supported)
+{
+ // Pre-calculate size of the image buffer, for convenience
+
+ // Determine the X dimension of the image buffer, in bytes.
+ // Along rows, pixels are stored 8 per byte.
+ // Not all display widths are divisible by 8. Need to make sure bytecount accommodates padding for these.
+ bufferRowSize = ((width - 1) / 8) + 1;
+
+ // Total size of image buffer, in bytes.
+ bufferSize = bufferRowSize * height;
+}
+
+void LCMEN213EFC1::begin(SPIClass *spi, uint8_t pin_dc, uint8_t pin_cs, uint8_t pin_busy, uint8_t pin_rst)
+{
+ this->spi = spi;
+ this->pin_dc = pin_dc;
+ this->pin_cs = pin_cs;
+ this->pin_busy = pin_busy;
+ this->pin_rst = pin_rst;
+
+ pinMode(pin_dc, OUTPUT);
+ pinMode(pin_cs, OUTPUT);
+ pinMode(pin_busy, INPUT);
+
+ // Reset is active low, hold high
+ pinMode(pin_rst, INPUT_PULLUP);
+
+ reset();
+}
+
+void LCMEN213EFC1::update(uint8_t *imageData, UpdateTypes type)
+{
+ this->updateType = type;
+ this->buffer = imageData;
+
+ reset();
+
+ // Config
+ if (updateType == FULL)
+ configFull();
+ else
+ configFast();
+
+ // Transfer image data
+ if (updateType == FULL) {
+ writeNewImage();
+ writeOldImage();
+ } else {
+ writeNewImage();
+ }
+
+ sendCommand(0x04); // Power on the panel voltage
+ wait();
+
+ sendCommand(0x12); // Begin executing the update
+
+ // Let the update run async, on display hardware. Base class will poll completion, then finalize.
+ // For a blocking update, call await after update
+ detachFromUpdate();
+}
+
+void LCMEN213EFC1::wait()
+{
+ // Busy when LOW
+ while (digitalRead(pin_busy) == LOW)
+ yield();
+}
+
+void LCMEN213EFC1::reset()
+{
+ pinMode(pin_rst, OUTPUT);
+ digitalWrite(pin_rst, LOW);
+ delay(10);
+ pinMode(pin_rst, INPUT_PULLUP);
+ wait();
+
+ sendCommand(0x12);
+ wait();
+}
+
+void LCMEN213EFC1::sendCommand(const uint8_t command)
+{
+ spi->beginTransaction(spiSettings);
+ digitalWrite(pin_dc, LOW); // DC pin low indicates command
+ digitalWrite(pin_cs, LOW);
+ spi->transfer(command);
+ digitalWrite(pin_cs, HIGH);
+ digitalWrite(pin_dc, HIGH);
+ spi->endTransaction();
+}
+
+void LCMEN213EFC1::sendData(uint8_t data)
+{
+ // spi->beginTransaction(spiSettings);
+ // digitalWrite(pin_dc, HIGH); // DC pin HIGH indicates data, instead of command
+ // digitalWrite(pin_cs, LOW);
+ // spi->transfer(data);
+ // digitalWrite(pin_cs, HIGH);
+ // digitalWrite(pin_dc, HIGH);
+ // spi->endTransaction();
+ sendData(&data, 1);
+}
+
+void LCMEN213EFC1::sendData(const uint8_t *data, uint32_t size)
+{
+ spi->beginTransaction(spiSettings);
+ digitalWrite(pin_dc, HIGH); // DC pin HIGH indicates data, instead of command
+ digitalWrite(pin_cs, LOW);
+
+ // Platform-specific SPI command
+ // Mothballing. This display model is only used by Heltec Wireless Paper (ESP32)
+#if defined(ARCH_ESP32)
+ spi->transferBytes(data, NULL, size); // NULL for a "write only" transfer
+#elif defined(ARCH_NRF52)
+ spi->transfer(data, NULL, size); // NULL for a "write only" transfer
+#else
+#error Not implemented yet? Feel free to add other platforms here.
+#endif
+
+ digitalWrite(pin_cs, HIGH);
+ digitalWrite(pin_dc, HIGH);
+ spi->endTransaction();
+}
+
+void LCMEN213EFC1::configFull()
+{
+ sendCommand(0x00); // Panel setting register
+ sendData(0b11 << 6 // Display resolution
+ | 1 << 4 // B&W only
+ | 1 << 3 // Vertical scan direction
+ | 1 << 2 // Horizontal scan direction
+ | 1 << 1 // Shutdown: no
+ | 1 << 0 // Reset: no
+ );
+
+ sendCommand(0x50); // VCOM and data interval setting register
+ sendData(0b10 << 6 // Border driven white
+ | 0b11 << 4 // Invert image colors: no
+ | 0b0111 << 0 // Interval between VCOM on and image data (default)
+ );
+}
+
+void LCMEN213EFC1::configFast()
+{
+ sendCommand(0x00); // Panel setting register
+ sendData(0b11 << 6 // Display resolution
+ | 1 << 5 // LUT from registers (set below)
+ | 1 << 4 // B&W only
+ | 1 << 3 // Vertical scan direction
+ | 1 << 2 // Horizontal scan direction
+ | 1 << 1 // Shutdown: no
+ | 1 << 0 // Reset: no
+ );
+
+ sendCommand(0x50); // VCOM and data interval setting register
+ sendData(0b11 << 6 // Border floating
+ | 0b01 << 4 // Invert image colors: no
+ | 0b0111 << 0 // Interval between VCOM on and image data (default)
+ );
+
+ // Load the various LUTs
+ sendCommand(0x20); // VCOM
+ sendData(LUT_FAST_VCOMDC, sizeof(LUT_FAST_VCOMDC));
+
+ sendCommand(0x21); // White -> White
+ sendData(LUT_FAST_WW, sizeof(LUT_FAST_WW));
+
+ sendCommand(0x22); // Black -> White
+ sendData(LUT_FAST_BW, sizeof(LUT_FAST_BW));
+
+ sendCommand(0x23); // White -> Black
+ sendData(LUT_FAST_WB, sizeof(LUT_FAST_WB));
+
+ sendCommand(0x24); // Black -> Black
+ sendData(LUT_FAST_BB, sizeof(LUT_FAST_BB));
+}
+
+void LCMEN213EFC1::writeNewImage()
+{
+ sendCommand(0x13);
+ sendData(buffer, bufferSize);
+}
+
+void LCMEN213EFC1::writeOldImage()
+{
+ sendCommand(0x10);
+ sendData(buffer, bufferSize);
+}
+
+void LCMEN213EFC1::detachFromUpdate()
+{
+ // To save power / cycles, displays can choose to specify an "expected duration" for various refresh types
+ // If we know a full-refresh takes at least 4 seconds, we can delay polling until 3 seconds have passed
+ // If not implemented, we'll just poll right from the get-go
+ switch (updateType) {
+ case FULL:
+ EInk::beginPolling(10, 3650);
+ break;
+ case FAST:
+ EInk::beginPolling(10, 720);
+ break;
+ default:
+ assert(false);
+ }
+}
+
+bool LCMEN213EFC1::isUpdateDone()
+{
+ // Busy when LOW
+ if (digitalRead(pin_busy) == LOW)
+ return false;
+ else
+ return true;
+}
+
+void LCMEN213EFC1::finalizeUpdate()
+{
+ // Power off the panel voltages
+ sendCommand(0x02);
+ wait();
+
+ // Put a copy of the image into the "old memory".
+ // Used with differential refreshes (e.g. FAST update), to determine which px need to move, and which can remain in place
+ // We need to keep the "old memory" up to date, because don't know whether next refresh will be FULL or FAST etc.
+ if (updateType != FULL) {
+ writeOldImage();
+ wait();
+ }
+}
+
+#endif // MESHTASTIC_INCLUDE_NICHE_GRAPHICS
\ No newline at end of file
diff --git a/src/graphics/niche/Drivers/EInk/LCMEN2R13EFC1.h b/src/graphics/niche/Drivers/EInk/LCMEN2R13EFC1.h
new file mode 100644
index 000000000..5c801c014
--- /dev/null
+++ b/src/graphics/niche/Drivers/EInk/LCMEN2R13EFC1.h
@@ -0,0 +1,68 @@
+/*
+
+E-Ink display driver
+ - LCMEN213EFC1
+ - Manufacturer: Wisevast
+ - Size: 2.13 inch
+ - Resolution: 122px x 250px
+ - Flex connector marking: HINK-E0213A162-FPC-A0 (Hidden, printed on back-side)
+
+Note: this display uses an uncommon controller IC, Fitipower JD79656.
+It is implemented as a "one-off", directly inheriting the EInk base class, unlike SSD16XX displays.
+
+*/
+
+#pragma once
+
+#ifdef MESHTASTIC_INCLUDE_NICHE_GRAPHICS
+
+#include "configuration.h"
+
+#include "./EInk.h"
+
+namespace NicheGraphics::Drivers
+{
+
+class LCMEN213EFC1 : public EInk
+{
+ // Display properties
+ private:
+ static constexpr uint32_t width = 122;
+ static constexpr uint32_t height = 250;
+ static constexpr UpdateTypes supported = (UpdateTypes)(FULL | FAST);
+
+ public:
+ LCMEN213EFC1();
+ void begin(SPIClass *spi, uint8_t pin_dc, uint8_t pin_cs, uint8_t pin_busy, uint8_t pin_rst);
+ void update(uint8_t *imageData, UpdateTypes type) override;
+
+ protected:
+ void wait();
+ void reset();
+ void sendCommand(const uint8_t command);
+ void sendData(const uint8_t data);
+ void sendData(const uint8_t *data, uint32_t size);
+ void configFull(); // Configure display for FULL refresh
+ void configFast(); // Configure display for FAST refresh
+ void writeNewImage();
+ void writeOldImage();
+
+ void detachFromUpdate();
+ bool isUpdateDone();
+ void finalizeUpdate();
+
+ protected:
+ uint8_t bufferOffsetX; // In bytes. Panel x=0 does not always align with controller x=0. Quirky internal wiring?
+ uint8_t bufferRowSize; // In bytes. Rows store 8 pixels per byte. Rounded up to fit (e.g. 122px would require 16 bytes)
+ uint32_t bufferSize; // In bytes. Rows * Columns
+ uint8_t *buffer;
+ UpdateTypes updateType;
+
+ uint8_t pin_dc, pin_cs, pin_busy, pin_rst;
+ SPIClass *spi;
+ SPISettings spiSettings = SPISettings(6000000, MSBFIRST, SPI_MODE0);
+};
+
+} // namespace NicheGraphics::Drivers
+
+#endif // MESHTASTIC_INCLUDE_NICHE_GRAPHICS
\ No newline at end of file
diff --git a/src/graphics/niche/Drivers/EInk/README.md b/src/graphics/niche/Drivers/EInk/README.md
new file mode 100644
index 000000000..ffe21e507
--- /dev/null
+++ b/src/graphics/niche/Drivers/EInk/README.md
@@ -0,0 +1,82 @@
+# NicheGraphics - E-Ink Driver
+
+A driver for E-Ink SPI displays. Suitable for re-use by various NicheGraphics UIs.
+
+Your UI should use the class `NicheGraphics::Drivers::EInk` .
+When you set up a hardware variant, you will use one of specific display model classes, which extend the EInk class.
+
+An example setup might look like this:
+
+```cpp
+void setupNicheGraphics()
+{
+ using namespace NicheGraphics;
+
+ // An imaginary UI
+ YourCustomUI *yourUI = new YourCustomUI();
+
+ // Setup SPI
+ SPIClass *hspi = new SPIClass(HSPI);
+ hspi->begin(PIN_EINK_SCLK, -1, PIN_EINK_MOSI, PIN_EINK_CS);
+
+ // Setup Enk driver
+ Drivers::EInk *driver = new Drivers::DEPG0290BNS800;
+ driver->begin(hspi, PIN_EINK_DC, PIN_EINK_CS, PIN_EINK_BUSY);
+
+ // Pass the driver to your UI
+ YourUI::driver = driver;
+}
+```
+
+## Methods
+
+### `update(uint8_t *imageData, UpdateTypes type, bool async=true)`
+
+Update the image on the display
+
+- _`imageData`_ to draw to the display.
+- _`type`_ which type of update to perform.
+ - `FULL`
+ - `FAST`
+ - (Other custom types may be possible)
+- _`async`_ whether to wait for update to complete, or continue code execution
+
+The imageData is a 1-bit image. X-Pixels are 8-per byte, with the MSB being the leftmost pixel. This was not an InkHUD design decision; it is the raw format accepted by the E-Ink display controllers ICs.
+
+_To-do: add a helper method to `InkHUD::Drivers::EInk` to do this arithmetic for you._
+
+```cpp
+uint16_t w = driver::width();
+uint16_t h = driver::height();
+
+uint8_t image[ (w/8) * h ]; // X pixels are 8-per-byte
+
+image[0] |= (1 << 7); // Set pixel x=0, y=0
+image[0] |= (1 << 0); // Set pixel x=7, y=0
+image[1] |= (1 << 7); // Set pixel x=8, y=0
+
+uint8_t x = 12;
+uint8_t y = 2;
+uint8_t yBytes = y * (w/8);
+uint8_t xBytes = x / 8;
+uint8_t xBits = (7-x) % 8;
+image[yByte + xByte] |= (1 << xBits); // Set pixel x=12, y=2
+```
+
+### `supports(UpdateTypes type)`
+
+Check if display supports a specific update type. `true` if supported.
+
+- _`type`_ type to check
+
+### `busy()`
+
+Check if display is already performing an `update()`. `true` if already updating.
+
+### `width()`
+
+Width of the display, in pixels. Note: most displays are portait. Your UI will need to implement rotation in software.
+
+### `height()`
+
+Height of the display, in pixels. Note: most displays are portrait. Your UI will need to implement rotation in software.
diff --git a/src/graphics/niche/Drivers/EInk/SSD16XX.cpp b/src/graphics/niche/Drivers/EInk/SSD16XX.cpp
new file mode 100644
index 000000000..d58e5b37a
--- /dev/null
+++ b/src/graphics/niche/Drivers/EInk/SSD16XX.cpp
@@ -0,0 +1,227 @@
+#include "./SSD16XX.h"
+
+#ifdef MESHTASTIC_INCLUDE_NICHE_GRAPHICS
+using namespace NicheGraphics::Drivers;
+
+SSD16XX::SSD16XX(uint16_t width, uint16_t height, UpdateTypes supported, uint8_t bufferOffsetX)
+ : EInk(width, height, supported), bufferOffsetX(bufferOffsetX)
+{
+ // Pre-calculate size of the image buffer, for convenience
+
+ // Determine the X dimension of the image buffer, in bytes.
+ // Along rows, pixels are stored 8 per byte.
+ // Not all display widths are divisible by 8. Need to make sure bytecount accommodates padding for these.
+ bufferRowSize = ((width - 1) / 8) + 1;
+
+ // Total size of image buffer, in bytes.
+ bufferSize = bufferRowSize * height;
+}
+
+void SSD16XX::begin(SPIClass *spi, uint8_t pin_dc, uint8_t pin_cs, uint8_t pin_busy, uint8_t pin_rst)
+{
+ this->spi = spi;
+ this->pin_dc = pin_dc;
+ this->pin_cs = pin_cs;
+ this->pin_busy = pin_busy;
+ this->pin_rst = pin_rst;
+
+ pinMode(pin_dc, OUTPUT);
+ pinMode(pin_cs, OUTPUT);
+ pinMode(pin_busy, INPUT);
+
+ // If using a reset pin, hold high
+ // Reset is active low for solmon systech ICs
+ if (pin_rst != 0xFF)
+ pinMode(pin_rst, INPUT_PULLUP);
+
+ reset();
+}
+
+void SSD16XX::wait()
+{
+ // Busy when HIGH
+ while (digitalRead(pin_busy) == HIGH)
+ yield();
+}
+
+void SSD16XX::reset()
+{
+ // Check if reset pin is defined
+ if (pin_rst != 0xFF) {
+ pinMode(pin_rst, OUTPUT);
+ digitalWrite(pin_rst, LOW);
+ delay(50);
+ pinMode(pin_rst, INPUT_PULLUP);
+ wait();
+ }
+
+ sendCommand(0x12);
+ wait();
+}
+
+void SSD16XX::sendCommand(const uint8_t command)
+{
+ spi->beginTransaction(spiSettings);
+ digitalWrite(pin_dc, LOW); // DC pin low indicates command
+ digitalWrite(pin_cs, LOW);
+ spi->transfer(command);
+ digitalWrite(pin_cs, HIGH);
+ digitalWrite(pin_dc, HIGH);
+ spi->endTransaction();
+}
+
+void SSD16XX::sendData(uint8_t data)
+{
+ // spi->beginTransaction(spiSettings);
+ // digitalWrite(pin_dc, HIGH); // DC pin HIGH indicates data, instead of command
+ // digitalWrite(pin_cs, LOW);
+ // spi->transfer(data);
+ // digitalWrite(pin_cs, HIGH);
+ // digitalWrite(pin_dc, HIGH);
+ // spi->endTransaction();
+ sendData(&data, 1);
+}
+
+void SSD16XX::sendData(const uint8_t *data, uint32_t size)
+{
+ spi->beginTransaction(spiSettings);
+ digitalWrite(pin_dc, HIGH); // DC pin HIGH indicates data, instead of command
+ digitalWrite(pin_cs, LOW);
+
+ // Platform-specific SPI command
+#if defined(ARCH_ESP32)
+ spi->transferBytes(data, NULL, size); // NULL for a "write only" transfer
+#elif defined(ARCH_NRF52)
+ spi->transfer(data, NULL, size); // NULL for a "write only" transfer
+#else
+#error Not implemented yet? Feel free to add other platforms here.
+#endif
+
+ digitalWrite(pin_cs, HIGH);
+ digitalWrite(pin_dc, HIGH);
+ spi->endTransaction();
+}
+
+void SSD16XX::configFullscreen()
+{
+ // Placing this code in a separate method because it's probably pretty consistent between displays
+ // Should make it tidier to override SSD16XX::configure
+
+ // Define the boundaries of the "fullscreen" region, for the controller IC
+ static const uint16_t sx = bufferOffsetX; // Notice the offset
+ static const uint16_t sy = 0;
+ static const uint16_t ex = bufferRowSize + bufferOffsetX - 1; // End is "max index", not "count". Minus 1 handles this
+ static const uint16_t ey = height;
+
+ // Split into bytes
+ static const uint8_t sy1 = sy & 0xFF;
+ static const uint8_t sy2 = (sy >> 8) & 0xFF;
+ static const uint8_t ey1 = ey & 0xFF;
+ static const uint8_t ey2 = (ey >> 8) & 0xFF;
+
+ // Data entry mode - Left to Right, Top to Bottom
+ sendCommand(0x11);
+ sendData(0x03);
+
+ // Select controller IC memory region to display a fullscreen image
+ sendCommand(0x44); // Memory X start - end
+ sendData(sx);
+ sendData(ex);
+ sendCommand(0x45); // Memory Y start - end
+ sendData(sy1);
+ sendData(sy2);
+ sendData(ey1);
+ sendData(ey2);
+
+ // Place the cursor at the start of this memory region, ready to send image data x=0 y=0
+ sendCommand(0x4E); // Memory cursor X
+ sendData(sx);
+ sendCommand(0x4F); // Memory cursor y
+ sendData(sy1);
+ sendData(sy2);
+}
+
+void SSD16XX::update(uint8_t *imageData, UpdateTypes type)
+{
+ this->updateType = type;
+ this->buffer = imageData;
+
+ reset();
+
+ configFullscreen();
+ configScanning(); // Virtual, unused by base class
+ configVoltages(); // Virtual, unused by base class
+ configWaveform(); // Virtual, unused by base class
+ wait();
+
+ if (updateType == FULL) {
+ writeNewImage();
+ writeOldImage();
+ } else {
+ writeNewImage();
+ }
+
+ configUpdateSequence();
+ sendCommand(0x20); // Begin executing the update
+
+ // Let the update run async, on display hardware. Base class will poll completion, then finalize.
+ // For a blocking update, call await after update
+ detachFromUpdate();
+}
+
+// Send SPI commands for controller IC to begin executing the refresh operation
+void SSD16XX::configUpdateSequence()
+{
+ switch (updateType) {
+ default:
+ sendCommand(0x22); // Set "update sequence"
+ sendData(0xF7); // Non-differential, load waveform from OTP
+ break;
+ }
+}
+
+void SSD16XX::writeNewImage()
+{
+ sendCommand(0x24);
+ sendData(buffer, bufferSize);
+}
+
+void SSD16XX::writeOldImage()
+{
+ sendCommand(0x26);
+ sendData(buffer, bufferSize);
+}
+
+void SSD16XX::detachFromUpdate()
+{
+ // To save power / cycles, displays can choose to specify an "expected duration" for various refresh types
+ // If we know a full-refresh takes at least 4 seconds, we can delay polling until 3 seconds have passed
+ // If not implemented, we'll just poll right from the get-go
+ switch (updateType) {
+ default:
+ EInk::beginPolling(100, 0);
+ }
+}
+
+bool SSD16XX::isUpdateDone()
+{
+ // Busy when HIGH
+ if (digitalRead(pin_busy) == HIGH)
+ return false;
+ else
+ return true;
+}
+
+void SSD16XX::finalizeUpdate()
+{
+ // Put a copy of the image into the "old memory".
+ // Used with differential refreshes (e.g. FAST update), to determine which px need to move, and which can remain in place
+ // We need to keep the "old memory" up to date, because don't know whether next refresh will be FULL or FAST etc.
+ if (updateType != FULL) {
+ writeNewImage(); // Only required by some controller variants. Todo: Override just for GDEY0154D678?
+ writeOldImage();
+ sendCommand(0x7F); // Terminate image write without update
+ wait();
+ }
+}
+#endif // MESHTASTIC_INCLUDE_NICHE_GRAPHICS
\ No newline at end of file
diff --git a/src/graphics/niche/Drivers/EInk/SSD16XX.h b/src/graphics/niche/Drivers/EInk/SSD16XX.h
new file mode 100644
index 000000000..f9077f188
--- /dev/null
+++ b/src/graphics/niche/Drivers/EInk/SSD16XX.h
@@ -0,0 +1,62 @@
+/*
+
+E-Ink base class for displays based on SSD16XX
+
+Most (but not all) SPI E-Ink displays use this family of controller IC.
+Implementing new SSD16XX displays should be fairly painless.
+See DEPG0154BNS800 and DEPG0290BNS800 for examples.
+
+*/
+
+#pragma once
+
+#ifdef MESHTASTIC_INCLUDE_NICHE_GRAPHICS
+
+#include "configuration.h"
+
+#include "./EInk.h"
+
+namespace NicheGraphics::Drivers
+{
+
+class SSD16XX : public EInk
+{
+ public:
+ SSD16XX(uint16_t width, uint16_t height, UpdateTypes supported, uint8_t bufferOffsetX = 0);
+ virtual void begin(SPIClass *spi, uint8_t pin_dc, uint8_t pin_cs, uint8_t pin_busy, uint8_t pin_rst = -1);
+ virtual void update(uint8_t *imageData, UpdateTypes type) override;
+
+ protected:
+ virtual void wait();
+ virtual void reset();
+ virtual void sendCommand(const uint8_t command);
+ virtual void sendData(const uint8_t data);
+ virtual void sendData(const uint8_t *data, uint32_t size);
+ virtual void configFullscreen(); // Select memory region on controller IC
+ virtual void configScanning() {} // Optional. First & last gates, scan direction, etc
+ virtual void configVoltages() {} // Optional. Manual panel voltages, soft-start, etc
+ virtual void configWaveform() {} // Optional. LUT, panel border, temperature sensor, etc
+ virtual void configUpdateSequence(); // Tell controller IC which operations to run
+
+ virtual void writeNewImage();
+ virtual void writeOldImage();
+
+ virtual void detachFromUpdate();
+ virtual bool isUpdateDone() override;
+ virtual void finalizeUpdate() override;
+
+ protected:
+ uint8_t bufferOffsetX; // In bytes. Panel x=0 does not always align with controller x=0. Quirky internal wiring?
+ uint8_t bufferRowSize; // In bytes. Rows store 8 pixels per byte. Rounded up to fit (e.g. 122px would require 16 bytes)
+ uint32_t bufferSize; // In bytes. Rows * Columns
+ uint8_t *buffer;
+ UpdateTypes updateType;
+
+ uint8_t pin_dc, pin_cs, pin_busy, pin_rst;
+ SPIClass *spi;
+ SPISettings spiSettings = SPISettings(4000000, MSBFIRST, SPI_MODE0);
+};
+
+} // namespace NicheGraphics::Drivers
+
+#endif // MESHTASTIC_INCLUDE_NICHE_GRAPHICS
\ No newline at end of file
diff --git a/src/graphics/niche/Drivers/README.md b/src/graphics/niche/Drivers/README.md
new file mode 100644
index 000000000..566558658
--- /dev/null
+++ b/src/graphics/niche/Drivers/README.md
@@ -0,0 +1,3 @@
+# NicheGraphics - Drivers
+
+Common drivers which can be used by various NicheGrapihcs UIs
diff --git a/src/graphics/niche/FlashData.h b/src/graphics/niche/FlashData.h
new file mode 100644
index 000000000..4a436d387
--- /dev/null
+++ b/src/graphics/niche/FlashData.h
@@ -0,0 +1,140 @@
+#ifdef MESHTASTIC_INCLUDE_NICHE_GRAPHICS
+
+/*
+
+Re-usable NicheGraphics tool
+
+Save settings / data to flash, without use of the Meshtastic Protobufs
+Avoid bloating everyone's protobuf code for our one-off UI implementations
+
+*/
+
+#pragma once
+
+#include "configuration.h"
+
+#include "SafeFile.h"
+
+namespace NicheGraphics
+{
+
+template class FlashData
+{
+ private:
+ static std::string getFilename(const char *label)
+ {
+ std::string filename;
+ filename += "/NicheGraphics";
+ filename += "/";
+ filename += label;
+ filename += ".data";
+
+ return filename;
+ }
+
+ static uint32_t getHash(T *data)
+ {
+ uint32_t hash = 0;
+
+ // Sum all bytes of the image buffer together
+ for (uint32_t i = 0; i < sizeof(T); i++)
+ hash ^= ((uint8_t *)data)[i] + 1;
+
+ return hash;
+ }
+
+ public:
+ static bool load(T *data, const char *label)
+ {
+ // Set false if we run into issues
+ bool okay = true;
+
+ // Get a filename based on the label
+ std::string filename = getFilename(label);
+
+#ifdef FSCom
+
+ // Check that the file *does* actually exist
+ if (!FSCom.exists(filename.c_str())) {
+ LOG_WARN("'%s' not found. Using default values", filename.c_str());
+ okay = false;
+ return okay;
+ }
+
+ // Open the file
+ auto f = FSCom.open(filename.c_str(), FILE_O_READ);
+
+ // If opened, start reading
+ if (f) {
+ LOG_INFO("Loading NicheGraphics data '%s'", filename.c_str());
+
+ // Create an object which will received data from flash
+ // We read here first, so we can verify the checksum, without committing to overwriting the *data object
+ // Allows us to retain any defaults that might be set after we declared *data, but before loading settings,
+ // in case the flash values are corrupt
+ T flashData;
+
+ // Read the actual data
+ f.readBytes((char *)&flashData, sizeof(T));
+
+ // Read the hash
+ uint32_t savedHash = 0;
+ f.readBytes((char *)&savedHash, sizeof(savedHash));
+
+ // Calculate hash of the loaded data, then compare with the saved hash
+ // If hash looks good, copy the values to the main data object
+ uint32_t calculatedHash = getHash(&flashData);
+ if (savedHash != calculatedHash) {
+ LOG_WARN("'%s' is corrupt (hash mismatch). Using default values", filename.c_str());
+ okay = false;
+ } else
+ *data = flashData;
+
+ f.close();
+ } else {
+ LOG_ERROR("Could not open / read %s", filename.c_str());
+ okay = false;
+ }
+#else
+ LOG_ERROR("Filesystem not implemented");
+ state = LoadFileState::NO_FILESYSTEM;
+ okay = false;
+#endif
+ return okay;
+ }
+
+ // Save module's custom data (settings?) to flash. Does use protobufs
+ static void save(T *data, const char *label)
+ {
+ // Get a filename based on the label
+ std::string filename = getFilename(label);
+
+#ifdef FSCom
+ FSCom.mkdir("/NicheGraphics");
+
+ auto f = SafeFile(filename.c_str(), true); // "true": full atomic. Write new data to temp file, then rename.
+
+ LOG_INFO("Saving %s", filename.c_str());
+
+ // Calculate a hash of the data
+ uint32_t hash = getHash(data);
+
+ f.write((uint8_t *)data, sizeof(T)); // Write the actualy data
+ f.write((uint8_t *)&hash, sizeof(hash)); // Append the hash
+
+ // f.flush();
+
+ bool writeSucceeded = f.close();
+
+ if (!writeSucceeded) {
+ LOG_ERROR("Can't write data!");
+ }
+#else
+ LOG_ERROR("ERROR: Filesystem not implemented\n");
+#endif
+ }
+};
+
+} // namespace NicheGraphics
+
+#endif
\ No newline at end of file
diff --git a/src/graphics/niche/Fonts/FreeSans6pt7b.h b/src/graphics/niche/Fonts/FreeSans6pt7b.h
new file mode 100644
index 000000000..c5bcc32c4
--- /dev/null
+++ b/src/graphics/niche/Fonts/FreeSans6pt7b.h
@@ -0,0 +1,129 @@
+#pragma once
+
+const uint8_t FreeSans6pt7bBitmaps[] PROGMEM = {
+ 0xAA, 0xA8, 0xC0, 0xF6, 0xA0, 0x24, 0x51, 0xF9, 0x42, 0x9F, 0x92, 0x28, 0x10, 0xE5, 0x55, 0x50, 0xE1, 0x65, 0x55, 0xE1, 0x00,
+ 0x71, 0x24, 0x89, 0x22, 0x50, 0x74, 0x02, 0x70, 0xA4, 0x49, 0x11, 0xC0, 0x70, 0x91, 0x23, 0x86, 0x12, 0xA2, 0x4E, 0xF4, 0xE0,
+ 0x5A, 0xAA, 0x94, 0x89, 0x12, 0x49, 0x29, 0x00, 0x27, 0x50, 0x21, 0x3E, 0x42, 0x00, 0xE0, 0xC0, 0x80, 0x24, 0xA4, 0xA4, 0x80,
+ 0x74, 0xE3, 0x18, 0xC6, 0x33, 0x70, 0x27, 0x92, 0x49, 0x20, 0x79, 0x10, 0x41, 0x08, 0xC6, 0x10, 0xFC, 0x79, 0x30, 0x43, 0x18,
+ 0x10, 0x71, 0x78, 0x08, 0x61, 0x8A, 0x49, 0x2F, 0xC2, 0x08, 0x7D, 0x04, 0x1E, 0x44, 0x10, 0x51, 0x78, 0x74, 0x61, 0xE8, 0xC6,
+ 0x31, 0x70, 0xF8, 0x44, 0x22, 0x11, 0x08, 0x40, 0x39, 0x34, 0x53, 0x39, 0x1C, 0x51, 0x38, 0x39, 0x3C, 0x71, 0x4C, 0xF0, 0x53,
+ 0x78, 0x82, 0x87, 0x01, 0xF1, 0x83, 0x04, 0xF8, 0x3E, 0x07, 0x06, 0x36, 0x40, 0x74, 0x42, 0x11, 0x10, 0x80, 0x20, 0x0F, 0x86,
+ 0x19, 0x9A, 0xA4, 0xD9, 0x13, 0x22, 0x56, 0xDA, 0x6E, 0x60, 0x06, 0x00, 0x3C, 0x00, 0x18, 0x18, 0x3C, 0x24, 0x24, 0x7E, 0x42,
+ 0x42, 0xC3, 0xFA, 0x18, 0x61, 0xFA, 0x18, 0x61, 0xFC, 0x3E, 0x63, 0x40, 0x40, 0xC0, 0x40, 0x41, 0x63, 0x3E, 0xF9, 0x0A, 0x1C,
+ 0x18, 0x30, 0x61, 0xC2, 0xF8, 0xFE, 0x08, 0x20, 0xFE, 0x08, 0x20, 0xFC, 0xFE, 0x08, 0x20, 0xFA, 0x08, 0x20, 0x80, 0x1E, 0x61,
+ 0x40, 0x40, 0xC7, 0x41, 0x41, 0x63, 0x1D, 0x83, 0x06, 0x0C, 0x1F, 0xF0, 0x60, 0xC1, 0x82, 0xFF, 0x80, 0x08, 0x42, 0x10, 0x87,
+ 0x29, 0x70, 0x85, 0x12, 0x45, 0x0D, 0x13, 0x22, 0x42, 0x86, 0x84, 0x21, 0x08, 0x42, 0x10, 0xF8, 0xC3, 0xC3, 0xC3, 0xA5, 0xA5,
+ 0xA5, 0x99, 0x99, 0x99, 0x83, 0x86, 0x8D, 0x19, 0x33, 0x62, 0xC3, 0x86, 0x1E, 0x31, 0x90, 0x68, 0x1C, 0x0A, 0x05, 0x06, 0xC6,
+ 0x1E, 0x00, 0xFA, 0x18, 0x61, 0xFA, 0x08, 0x20, 0x80, 0x1E, 0x31, 0x90, 0x68, 0x1C, 0x0A, 0x05, 0x06, 0xC6, 0x1F, 0x00, 0x00,
+ 0xFD, 0x0E, 0x1C, 0x2F, 0x90, 0xA1, 0x42, 0x86, 0x7A, 0x18, 0x30, 0x78, 0x38, 0x61, 0x78, 0xFE, 0x20, 0x40, 0x81, 0x02, 0x04,
+ 0x08, 0x10, 0x83, 0x06, 0x0C, 0x18, 0x30, 0x60, 0xE2, 0x78, 0xC2, 0x42, 0x42, 0x64, 0x24, 0x24, 0x38, 0x18, 0x18, 0xC4, 0x28,
+ 0xCD, 0x29, 0x25, 0x24, 0xA4, 0x52, 0x8C, 0x61, 0x8C, 0x31, 0x80, 0x42, 0x66, 0x24, 0x18, 0x18, 0x18, 0x24, 0x46, 0x42, 0xC3,
+ 0x42, 0x24, 0x34, 0x18, 0x08, 0x08, 0x08, 0x08, 0x7E, 0x0C, 0x30, 0x41, 0x06, 0x18, 0x20, 0xFE, 0xEA, 0xAA, 0xAB, 0x92, 0x24,
+ 0x89, 0x20, 0xE9, 0x24, 0x92, 0x49, 0x70, 0x46, 0xA9, 0x10, 0xFE, 0x40, 0x79, 0x20, 0x4F, 0xC6, 0x37, 0x40, 0x84, 0x3D, 0x18,
+ 0xC6, 0x31, 0xF0, 0x39, 0x3C, 0x20, 0xC1, 0x33, 0x80, 0x04, 0x13, 0xD3, 0xC6, 0x1C, 0x53, 0x3C, 0x39, 0x38, 0x7F, 0x81, 0x13,
+ 0x80, 0x6B, 0xA4, 0x92, 0x40, 0x35, 0x3C, 0x61, 0xC5, 0x33, 0x41, 0x4D, 0xE0, 0x84, 0x3D, 0x38, 0xC6, 0x31, 0x88, 0xBF, 0x80,
+ 0x45, 0x55, 0x57, 0x84, 0x25, 0x4E, 0x52, 0xD2, 0x88, 0xFF, 0x80, 0xF7, 0x99, 0x91, 0x91, 0x91, 0x91, 0x91, 0xF4, 0x63, 0x18,
+ 0xC6, 0x20, 0x39, 0x3C, 0x61, 0xC5, 0x33, 0x80, 0xF4, 0x63, 0x18, 0xC7, 0xD0, 0x80, 0x3D, 0x3C, 0x61, 0xC5, 0x37, 0x41, 0x04,
+ 0xF2, 0x49, 0x20, 0x79, 0x24, 0x1C, 0x0B, 0x27, 0x80, 0x5D, 0x24, 0x93, 0x8C, 0x63, 0x18, 0xCF, 0xA0, 0x85, 0x24, 0x92, 0x30,
+ 0xC3, 0x00, 0x89, 0x2C, 0x96, 0x4A, 0xA5, 0x61, 0x30, 0x98, 0x49, 0x23, 0x08, 0x31, 0x2C, 0x80, 0x89, 0x24, 0x94, 0x50, 0xC2,
+ 0x08, 0x21, 0x00, 0x78, 0x44, 0x46, 0x23, 0xE0, 0x6A, 0xAA, 0xA9, 0xFF, 0xE0, 0x95, 0x55, 0x56, 0x66, 0x60};
+
+const GFXglyph FreeSans6pt7bGlyphs[] PROGMEM = {{0, 0, 0, 3, 0, 1}, // 0x20 ' '
+ {0, 2, 9, 4, 1, -8}, // 0x21 '!'
+ {3, 4, 3, 4, 0, -8}, // 0x22 '"'
+ {5, 7, 8, 7, 0, -7}, // 0x23 '#'
+ {12, 6, 11, 7, 0, -9}, // 0x24 '$'
+ {21, 10, 9, 11, 0, -8}, // 0x25 '%'
+ {33, 7, 9, 8, 1, -8}, // 0x26 '&'
+ {41, 1, 3, 2, 1, -8}, // 0x27 '''
+ {42, 2, 11, 4, 1, -8}, // 0x28 '('
+ {45, 3, 11, 4, 0, -8}, // 0x29 ')'
+ {50, 4, 3, 5, 0, -8}, // 0x2A '*'
+ {52, 5, 5, 7, 1, -4}, // 0x2B '+'
+ {56, 1, 3, 3, 1, 0}, // 0x2C ','
+ {57, 2, 1, 4, 1, -3}, // 0x2D '-'
+ {58, 1, 1, 3, 1, 0}, // 0x2E '.'
+ {59, 3, 9, 3, 0, -8}, // 0x2F '/'
+ {63, 5, 9, 7, 1, -8}, // 0x30 '0'
+ {69, 3, 9, 7, 1, -8}, // 0x31 '1'
+ {73, 6, 9, 7, 0, -8}, // 0x32 '2'
+ {80, 6, 9, 7, 0, -8}, // 0x33 '3'
+ {87, 6, 9, 7, 0, -8}, // 0x34 '4'
+ {94, 6, 9, 7, 0, -8}, // 0x35 '5'
+ {101, 5, 9, 7, 1, -8}, // 0x36 '6'
+ {107, 5, 9, 7, 1, -8}, // 0x37 '7'
+ {113, 6, 9, 7, 0, -8}, // 0x38 '8'
+ {120, 6, 9, 7, 0, -8}, // 0x39 '9'
+ {127, 1, 7, 3, 1, -6}, // 0x3A ':'
+ {128, 1, 8, 3, 1, -5}, // 0x3B ';'
+ {129, 5, 6, 7, 1, -5}, // 0x3C '<'
+ {133, 5, 3, 7, 1, -3}, // 0x3D '='
+ {135, 5, 6, 7, 1, -5}, // 0x3E '>'
+ {139, 5, 9, 7, 1, -8}, // 0x3F '?'
+ {145, 11, 11, 12, 0, -8}, // 0x40 '@'
+ {161, 8, 9, 8, 0, -8}, // 0x41 'A'
+ {170, 6, 9, 8, 1, -8}, // 0x42 'B'
+ {177, 8, 9, 9, 0, -8}, // 0x43 'C'
+ {186, 7, 9, 8, 1, -8}, // 0x44 'D'
+ {194, 6, 9, 8, 1, -8}, // 0x45 'E'
+ {201, 6, 9, 7, 1, -8}, // 0x46 'F'
+ {208, 8, 9, 9, 0, -8}, // 0x47 'G'
+ {217, 7, 9, 9, 1, -8}, // 0x48 'H'
+ {225, 1, 9, 3, 1, -8}, // 0x49 'I'
+ {227, 5, 9, 6, 0, -8}, // 0x4A 'J'
+ {233, 7, 9, 8, 1, -8}, // 0x4B 'K'
+ {241, 5, 9, 7, 1, -8}, // 0x4C 'L'
+ {247, 8, 9, 10, 1, -8}, // 0x4D 'M'
+ {256, 7, 9, 9, 1, -8}, // 0x4E 'N'
+ {264, 9, 9, 9, 0, -8}, // 0x4F 'O'
+ {275, 6, 9, 8, 1, -8}, // 0x50 'P'
+ {282, 9, 10, 9, 0, -8}, // 0x51 'Q'
+ {294, 7, 9, 9, 1, -8}, // 0x52 'R'
+ {302, 6, 9, 8, 1, -8}, // 0x53 'S'
+ {309, 7, 9, 8, 0, -8}, // 0x54 'T'
+ {317, 7, 9, 9, 1, -8}, // 0x55 'U'
+ {325, 8, 9, 8, 0, -8}, // 0x56 'V'
+ {334, 11, 9, 11, 0, -8}, // 0x57 'W'
+ {347, 8, 9, 8, 0, -8}, // 0x58 'X'
+ {356, 8, 9, 8, 0, -8}, // 0x59 'Y'
+ {365, 7, 9, 7, 0, -8}, // 0x5A 'Z'
+ {373, 2, 12, 3, 1, -8}, // 0x5B '['
+ {376, 3, 9, 3, 0, -8}, // 0x5C '\'
+ {380, 3, 12, 3, 0, -8}, // 0x5D ']'
+ {385, 4, 5, 6, 1, -8}, // 0x5E '^'
+ {388, 7, 1, 7, 0, 2}, // 0x5F '_'
+ {389, 3, 1, 3, 0, -8}, // 0x60 '`'
+ {390, 6, 7, 7, 0, -6}, // 0x61 'a'
+ {396, 5, 9, 7, 1, -8}, // 0x62 'b'
+ {402, 6, 7, 6, 0, -6}, // 0x63 'c'
+ {408, 6, 9, 7, 0, -8}, // 0x64 'd'
+ {415, 6, 7, 6, 0, -6}, // 0x65 'e'
+ {421, 3, 9, 3, 0, -8}, // 0x66 'f'
+ {425, 6, 10, 7, 0, -6}, // 0x67 'g'
+ {433, 5, 9, 6, 1, -8}, // 0x68 'h'
+ {439, 1, 9, 3, 1, -8}, // 0x69 'i'
+ {441, 2, 12, 3, 0, -8}, // 0x6A 'j'
+ {444, 5, 9, 6, 1, -8}, // 0x6B 'k'
+ {450, 1, 9, 3, 1, -8}, // 0x6C 'l'
+ {452, 8, 7, 10, 1, -6}, // 0x6D 'm'
+ {459, 5, 7, 6, 1, -6}, // 0x6E 'n'
+ {464, 6, 7, 6, 0, -6}, // 0x6F 'o'
+ {470, 5, 9, 7, 1, -6}, // 0x70 'p'
+ {476, 6, 9, 7, 0, -6}, // 0x71 'q'
+ {483, 3, 7, 4, 1, -6}, // 0x72 'r'
+ {486, 6, 7, 6, 0, -6}, // 0x73 's'
+ {492, 3, 8, 3, 0, -7}, // 0x74 't'
+ {495, 5, 7, 6, 1, -6}, // 0x75 'u'
+ {500, 6, 7, 6, 0, -6}, // 0x76 'v'
+ {506, 9, 7, 9, 0, -6}, // 0x77 'w'
+ {514, 6, 7, 6, 0, -6}, // 0x78 'x'
+ {520, 6, 10, 6, 0, -6}, // 0x79 'y'
+ {528, 5, 7, 6, 0, -6}, // 0x7A 'z'
+ {533, 2, 12, 4, 1, -8}, // 0x7B '{'
+ {536, 1, 11, 3, 1, -8}, // 0x7C '|'
+ {538, 2, 12, 4, 1, -8}, // 0x7D '}'
+ {541, 6, 2, 6, 0, -4}}; // 0x7E '~'
+
+const GFXfont FreeSans6pt7b PROGMEM = {(uint8_t *)FreeSans6pt7bBitmaps, (GFXglyph *)FreeSans6pt7bGlyphs, 0x20, 0x7E, 14};
+
+// Approx. 1215 bytes
diff --git a/src/graphics/niche/Fonts/FreeSans6pt8bCyrillic.h b/src/graphics/niche/Fonts/FreeSans6pt8bCyrillic.h
new file mode 100644
index 000000000..49f03d4e1
--- /dev/null
+++ b/src/graphics/niche/Fonts/FreeSans6pt8bCyrillic.h
@@ -0,0 +1,302 @@
+/*
+
+Uses Windows-1251 encoding to map translingual Cyrillic characters to range between (uint8_t)127 and (uint8_t)255
+https://en.wikipedia.org/wiki/Windows-1251
+
+Cyrillic characters present to the firmware as UTF8.
+A Niche Graphics implementation needs to identify these, and subsitute the appropriate Windows-1251 char value.
+
+*/
+
+#pragma once
+
+const uint8_t FreeSans6pt8bCyrillicBitmaps[] PROGMEM = {
+ 0xFF, 0xA0, 0xC0, 0xFF, 0xA0, 0xC0, 0xB6, 0x80, 0x24, 0x51, 0xF9, 0x42, 0x9F, 0x92, 0x28, 0x31, 0x75, 0x54, 0x78, 0x79, 0x75,
+ 0x7C, 0x41, 0x00, 0x01, 0x1C, 0x49, 0x22, 0x50, 0x74, 0x02, 0x60, 0xA4, 0x49, 0x11, 0xC0, 0x21, 0x44, 0x94, 0x62, 0x59, 0xE2,
+ 0xF4, 0xE0, 0x6A, 0xAA, 0x90, 0x48, 0x92, 0x49, 0x4A, 0x00, 0x5D, 0x40, 0x21, 0x09, 0xF2, 0x10, 0xE0, 0xC0, 0x80, 0x25, 0x25,
+ 0x24, 0x26, 0xA3, 0x18, 0xC6, 0x31, 0xF0, 0x27, 0x92, 0x49, 0x20, 0x11, 0xB4, 0x41, 0x0C, 0xC6, 0x10, 0xFC, 0x26, 0xA2, 0x13,
+ 0x04, 0x31, 0xF0, 0x08, 0x61, 0x8A, 0x49, 0x2F, 0xC2, 0x08, 0xFF, 0xE1, 0x4D, 0x84, 0x31, 0xF0, 0x26, 0xE3, 0x0F, 0x46, 0x31,
+ 0xF0, 0xFF, 0xC4, 0x22, 0x11, 0x08, 0x40, 0x11, 0xA4, 0x51, 0x39, 0x1C, 0x51, 0x78, 0x11, 0xA4, 0x71, 0x45, 0xF0, 0x51, 0x78,
+ 0xC0, 0x30, 0xC0, 0x36, 0x1F, 0x20, 0xE0, 0x80, 0xF8, 0x3E, 0xC1, 0xC2, 0xE8, 0x00, 0x74, 0x62, 0x11, 0x10, 0x80, 0x20, 0x0F,
+ 0x06, 0x18, 0x81, 0xA7, 0xD4, 0x93, 0x22, 0x64, 0x4A, 0x7E, 0x60, 0x06, 0x00, 0x3C, 0x00, 0x18, 0x18, 0x1C, 0x24, 0x24, 0x7E,
+ 0x42, 0x42, 0xC3, 0xFA, 0x38, 0x61, 0xFA, 0x18, 0x61, 0xFC, 0x38, 0x8A, 0x0C, 0x08, 0x10, 0x20, 0xE3, 0x7C, 0xF9, 0x1A, 0x1C,
+ 0x18, 0x30, 0x60, 0xC2, 0xF8, 0xFE, 0x08, 0x20, 0xFE, 0x08, 0x20, 0xFC, 0xFE, 0x08, 0x20, 0xFA, 0x08, 0x20, 0x80, 0x3C, 0x46,
+ 0x82, 0x80, 0x8F, 0x81, 0x83, 0xC3, 0x7D, 0x83, 0x06, 0x0C, 0x1F, 0xF0, 0x60, 0xC1, 0x82, 0xFF, 0x80, 0x08, 0x42, 0x10, 0x86,
+ 0x31, 0x78, 0x87, 0x1A, 0x65, 0x8F, 0x1A, 0x22, 0x42, 0x86, 0x84, 0x21, 0x08, 0x42, 0x10, 0xF8, 0xC3, 0xC3, 0xC3, 0xA5, 0xA5,
+ 0xA5, 0x99, 0x99, 0x99, 0x83, 0x87, 0x8D, 0x19, 0x32, 0x62, 0xC3, 0x86, 0x1E, 0x11, 0x90, 0x48, 0x1C, 0x0A, 0x05, 0x06, 0xC2,
+ 0x3E, 0x00, 0xFA, 0x18, 0x61, 0xFE, 0x08, 0x20, 0x80, 0x1E, 0x11, 0x90, 0x48, 0x1C, 0x0A, 0x05, 0x06, 0xC6, 0x3F, 0x00, 0xFD,
+ 0x0E, 0x0C, 0x1F, 0xD0, 0xA0, 0xC1, 0x82, 0x7A, 0x18, 0x70, 0x78, 0x38, 0x61, 0x7C, 0xFE, 0x20, 0x40, 0x81, 0x02, 0x04, 0x08,
+ 0x10, 0x83, 0x06, 0x0C, 0x18, 0x30, 0x60, 0xC3, 0x7C, 0xC3, 0x42, 0x42, 0x26, 0x24, 0x24, 0x14, 0x18, 0x18, 0xC4, 0x28, 0xC5,
+ 0x39, 0xA5, 0x24, 0xA4, 0x52, 0x8C, 0x71, 0x8C, 0x30, 0x80, 0x87, 0x34, 0x8C, 0x30, 0xC4, 0xB3, 0x84, 0xC3, 0x42, 0x26, 0x24,
+ 0x18, 0x18, 0x08, 0x08, 0x08, 0x7E, 0x0C, 0x10, 0x41, 0x06, 0x08, 0x20, 0xFE, 0xEA, 0xAA, 0xAB, 0x92, 0x24, 0x89, 0x20, 0xED,
+ 0xB6, 0xDB, 0x6D, 0xF0, 0x46, 0xAA, 0x90, 0xFC, 0x90, 0xFC, 0x4F, 0x98, 0xFC, 0x84, 0x21, 0xF8, 0xC6, 0x31, 0xF0, 0x79, 0x18,
+ 0x20, 0x45, 0xE0, 0x04, 0x10, 0x5F, 0xC6, 0x18, 0x51, 0x7C, 0xFC, 0x7F, 0x08, 0xF8, 0x29, 0x74, 0x92, 0x40, 0x7D, 0x18, 0x61,
+ 0x45, 0xF0, 0x52, 0x30, 0x84, 0x21, 0xF8, 0xC6, 0x31, 0x88, 0xDF, 0x80, 0x51, 0x55, 0x56, 0x84, 0x21, 0x2A, 0x72, 0x92, 0x98,
+ 0xFF, 0x80, 0xFF, 0x99, 0x99, 0x99, 0x99, 0x99, 0xFC, 0x63, 0x18, 0xC4, 0x79, 0x18, 0x71, 0x45, 0xE0, 0xFC, 0x63, 0x18, 0xFA,
+ 0x10, 0x80, 0x7D, 0x18, 0x61, 0x45, 0xF0, 0x41, 0x04, 0xF2, 0x49, 0x00, 0x79, 0x07, 0x02, 0xCD, 0xE0, 0x4B, 0xA4, 0x93, 0x8C,
+ 0x63, 0x18, 0xFC, 0xCD, 0x24, 0x94, 0x30, 0xC0, 0x99, 0x59, 0x55, 0x56, 0x66, 0x26, 0x96, 0x66, 0x99, 0xCA, 0x52, 0x63, 0x18,
+ 0x84, 0x40, 0x78, 0xC4, 0x44, 0x7C, 0x6A, 0xAA, 0xA9, 0xFF, 0xF0, 0xC9, 0x24, 0x4A, 0x49, 0x40, 0xE8, 0xC0, 0xFE, 0x18, 0x61,
+ 0x86, 0x18, 0x61, 0xFC, 0xFC, 0x08, 0x04, 0x02, 0x01, 0xF0, 0x8C, 0x46, 0x23, 0x11, 0x80, 0xC0, 0xC0, 0x10, 0x8F, 0xE0, 0x82,
+ 0x08, 0x20, 0x82, 0x08, 0x00, 0x64, 0x0F, 0x88, 0x88, 0x80, 0x3D, 0x0C, 0x2E, 0xF9, 0x04, 0x0F, 0x7C, 0x08, 0x81, 0x10, 0x22,
+ 0x04, 0x7C, 0x88, 0x51, 0x0A, 0x21, 0x87, 0xC0, 0x84, 0x10, 0x82, 0x10, 0x42, 0x0F, 0xFD, 0x08, 0xA1, 0x0C, 0x23, 0x87, 0xC0,
+ 0x10, 0x88, 0xE6, 0xB3, 0x8C, 0x28, 0x92, 0x28, 0xC0, 0xFC, 0x08, 0x04, 0x02, 0x01, 0xF0, 0x8C, 0x46, 0x23, 0x11, 0x80, 0x83,
+ 0x06, 0x0C, 0x18, 0x30, 0x60, 0xC1, 0xFE, 0x20, 0x40, 0x43, 0xC4, 0x1F, 0x45, 0x14, 0x51, 0x44, 0x11, 0x80, 0x78, 0x24, 0x13,
+ 0xC9, 0x14, 0x8E, 0x7C, 0x88, 0x44, 0x3F, 0xD1, 0x38, 0x8C, 0x78, 0x60, 0x9A, 0xCC, 0xA9, 0x43, 0xC4, 0x1F, 0x45, 0x14, 0x51,
+ 0x44, 0x8C, 0x63, 0x18, 0xFC, 0x80, 0x24, 0x33, 0x0A, 0x36, 0x45, 0x8E, 0x0C, 0x10, 0x60, 0x80, 0x70, 0x22, 0x95, 0xA8, 0xC4,
+ 0x23, 0x10, 0x08, 0x42, 0x10, 0x86, 0x31, 0x78, 0x07, 0xF8, 0x20, 0x82, 0x08, 0x20, 0x82, 0x00, 0x28, 0x0F, 0xE0, 0x82, 0x0F,
+ 0xE0, 0x82, 0x0F, 0xC0, 0x38, 0x8A, 0x0C, 0x0F, 0x90, 0x20, 0xE3, 0x7C, 0x51, 0x55, 0x56, 0xA1, 0x24, 0x92, 0x49, 0x00, 0xFF,
+ 0x80, 0xDF, 0x80, 0x27, 0xC9, 0x24, 0x8A, 0x28, 0xA2, 0x8B, 0xF8, 0x20, 0x80, 0x28, 0xA0, 0x1E, 0x47, 0xFC, 0x11, 0x78, 0x88,
+ 0x44, 0x32, 0x59, 0xDA, 0xCD, 0x66, 0x6B, 0x32, 0x89, 0x80, 0x79, 0x1F, 0x30, 0x45, 0xE0, 0x7A, 0x18, 0x70, 0x78, 0x38, 0x61,
+ 0x7C, 0x79, 0x07, 0x02, 0xCD, 0xE0, 0xB4, 0x24, 0x92, 0x40, 0x18, 0x18, 0x3C, 0x24, 0x24, 0x7E, 0x42, 0x42, 0xC3, 0xFE, 0x08,
+ 0x20, 0xFE, 0x18, 0x61, 0xFC, 0xFA, 0x38, 0x61, 0xFA, 0x18, 0x61, 0xFC, 0xFE, 0x08, 0x20, 0x82, 0x08, 0x20, 0x80, 0x1F, 0x08,
+ 0x84, 0x42, 0x21, 0x10, 0x88, 0x44, 0x42, 0xFF, 0xC0, 0x60, 0x20, 0xFE, 0x08, 0x20, 0xFE, 0x08, 0x20, 0xFC, 0x88, 0xA4, 0x9A,
+ 0x87, 0xC1, 0xC1, 0xF1, 0xAD, 0x92, 0x88, 0x80, 0x7A, 0x18, 0x41, 0x38, 0x18, 0x61, 0x7C, 0x87, 0x0E, 0x2C, 0x59, 0x34, 0x68,
+ 0xE1, 0xC2, 0x28, 0x22, 0x1C, 0x38, 0xB1, 0x64, 0xD1, 0xA3, 0x87, 0x08, 0x8E, 0x6B, 0x38, 0xC2, 0x89, 0x22, 0x8C, 0x3E, 0x44,
+ 0x89, 0x12, 0x24, 0x58, 0xA1, 0xC2, 0xC3, 0xC3, 0xC3, 0xA5, 0xA5, 0xA5, 0x99, 0x99, 0x99, 0x83, 0x06, 0x0C, 0x1F, 0xF0, 0x60,
+ 0xC1, 0x82, 0x3C, 0x46, 0x83, 0x81, 0x81, 0x81, 0x81, 0xC2, 0x7C, 0xFF, 0x06, 0x0C, 0x18, 0x30, 0x60, 0xC1, 0x82, 0xFA, 0x18,
+ 0x61, 0xFE, 0x08, 0x20, 0x80, 0x38, 0x8A, 0x0C, 0x08, 0x10, 0x20, 0xE3, 0x7C, 0xFE, 0x20, 0x40, 0x81, 0x02, 0x04, 0x08, 0x10,
+ 0xC2, 0x8D, 0x91, 0x63, 0x83, 0x04, 0x18, 0x20, 0x08, 0x1E, 0x32, 0xD1, 0x38, 0x8C, 0x4F, 0x2C, 0xFC, 0x08, 0x00, 0x87, 0x34,
+ 0x8C, 0x30, 0xC4, 0xB3, 0x84, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0xFF, 0x01, 0x01, 0x8E, 0x38, 0xE3, 0x8D, 0xF0,
+ 0xC3, 0x0C, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0xFF, 0x99, 0x4C, 0xA6, 0x53, 0x29, 0x94, 0xCA, 0x65, 0x32, 0xFF,
+ 0x80, 0x40, 0x20, 0xF0, 0x04, 0x01, 0x00, 0x40, 0x1F, 0x84, 0x21, 0x0C, 0x42, 0x1F, 0x00, 0x81, 0xC0, 0xE0, 0x70, 0x3F, 0xDC,
+ 0x2E, 0x17, 0x0B, 0xF9, 0x80, 0x82, 0x08, 0x20, 0xFE, 0x18, 0x61, 0xF8, 0x79, 0x8A, 0x18, 0x13, 0xE0, 0x60, 0xC2, 0x7C, 0x87,
+ 0x26, 0x39, 0x06, 0x41, 0xF0, 0x64, 0x19, 0x06, 0x63, 0x8F, 0x80, 0x7E, 0x18, 0x61, 0x7C, 0xD6, 0x71, 0x84, 0x79, 0x11, 0xD9,
+ 0xCD, 0xD0, 0x0D, 0xC4, 0x1E, 0x47, 0x1C, 0x51, 0x78, 0xF4, 0xBD, 0x29, 0xF8, 0xF8, 0x88, 0x88, 0x3C, 0x48, 0x91, 0x22, 0x5F,
+ 0xE0, 0x80, 0x79, 0x1F, 0xF0, 0x45, 0xE0, 0x92, 0x54, 0x38, 0x3C, 0x56, 0x93, 0x78, 0x23, 0x82, 0xCD, 0xE0, 0x9C, 0xEB, 0x5C,
+ 0xC4, 0x70, 0x27, 0x3A, 0xD7, 0x31, 0x9A, 0xCC, 0xA9, 0x7A, 0x52, 0x94, 0xE4, 0x8F, 0x3D, 0x6D, 0xA6, 0x90, 0x8C, 0x7F, 0x18,
+ 0xC4, 0x79, 0x1C, 0x71, 0x45, 0xE0, 0xFC, 0x63, 0x18, 0xC4, 0xFC, 0x63, 0x18, 0xFA, 0x10, 0x80, 0x79, 0x1C, 0x30, 0x45, 0xE0,
+ 0xF9, 0x08, 0x42, 0x10, 0x8A, 0x56, 0xA3, 0x10, 0x8C, 0x40, 0x04, 0x01, 0x07, 0xF9, 0x31, 0xC4, 0x71, 0x14, 0xC5, 0xFE, 0x04,
+ 0x01, 0x00, 0x40, 0x4B, 0x8C, 0x65, 0xE4, 0x8A, 0x28, 0xA2, 0x8B, 0xF0, 0x40, 0x99, 0x97, 0x11, 0x96, 0x59, 0x65, 0x97, 0xF0,
+ 0x95, 0x2A, 0x54, 0xA9, 0x5F, 0xC0, 0x80, 0xF0, 0x20, 0x78, 0x91, 0x23, 0xC0, 0x86, 0x1F, 0x63, 0x8F, 0xD0, 0x84, 0x3D, 0x18,
+ 0xF8, 0xF4, 0xDE, 0x19, 0xF8, 0x9E, 0xA2, 0xE1, 0xA1, 0xA2, 0x9E, 0xFC, 0x7E, 0xD4, 0xC4,
+};
+
+const GFXglyph FreeSans6pt8bCyrillicGlyphs[] PROGMEM = {
+ {0, 0, 0, 3, 0, 0}, // 0x20 ' '
+ {3, 2, 9, 3, 1, -8}, // 0x21 '!'
+ {6, 3, 3, 4, 1, -8}, // 0x22 '"'
+ {8, 7, 8, 7, 0, -7}, // 0x23 '#'
+ {15, 6, 11, 7, 0, -8}, // 0x24 '$'
+ {24, 10, 9, 11, 0, -8}, // 0x25 '%'
+ {36, 6, 9, 8, 1, -8}, // 0x26 '&'
+ {43, 1, 3, 2, 1, -8}, // 0x27 '''
+ {44, 2, 10, 4, 1, -7}, // 0x28 '('
+ {47, 3, 11, 4, 0, -7}, // 0x29 ')'
+ {52, 3, 4, 5, 1, -8}, // 0x2A '*'
+ {54, 5, 6, 7, 1, -5}, // 0x2B '+'
+ {58, 1, 3, 3, 1, 0}, // 0x2C ','
+ {59, 2, 1, 4, 1, -3}, // 0x2D '-'
+ {60, 1, 1, 3, 1, 0}, // 0x2E '.'
+ {61, 3, 8, 3, 0, -7}, // 0x2F '/'
+ {64, 5, 9, 7, 1, -8}, // 0x30 '0'
+ {70, 3, 9, 7, 1, -8}, // 0x31 '1'
+ {74, 6, 9, 7, 0, -8}, // 0x32 '2'
+ {81, 5, 9, 7, 1, -8}, // 0x33 '3'
+ {87, 6, 9, 7, 0, -8}, // 0x34 '4'
+ {94, 5, 9, 7, 1, -8}, // 0x35 '5'
+ {100, 5, 9, 7, 1, -8}, // 0x36 '6'
+ {106, 5, 9, 7, 1, -8}, // 0x37 '7'
+ {112, 6, 9, 7, 0, -8}, // 0x38 '8'
+ {119, 6, 9, 7, 0, -8}, // 0x39 '9'
+ {126, 2, 6, 3, 1, -5}, // 0x3A ':'
+ {128, 2, 8, 3, 1, -5}, // 0x3B ';'
+ {130, 5, 5, 7, 1, -4}, // 0x3C '<'
+ {134, 5, 3, 7, 1, -3}, // 0x3D '='
+ {136, 5, 5, 7, 1, -4}, // 0x3E '>'
+ {140, 5, 9, 7, 1, -8}, // 0x3F '?'
+ {146, 11, 11, 12, 0, -8}, // 0x40 '@'
+ {162, 8, 9, 8, 0, -8}, // 0x41 'A'
+ {171, 6, 9, 8, 1, -8}, // 0x42 'B'
+ {178, 7, 9, 9, 1, -8}, // 0x43 'C'
+ {186, 7, 9, 9, 1, -8}, // 0x44 'D'
+ {194, 6, 9, 8, 1, -8}, // 0x45 'E'
+ {201, 6, 9, 7, 1, -8}, // 0x46 'F'
+ {208, 8, 9, 9, 1, -8}, // 0x47 'G'
+ {217, 7, 9, 9, 1, -8}, // 0x48 'H'
+ {225, 1, 9, 3, 1, -8}, // 0x49 'I'
+ {227, 5, 9, 6, 0, -8}, // 0x4A 'J'
+ {233, 7, 9, 8, 1, -8}, // 0x4B 'K'
+ {241, 5, 9, 7, 1, -8}, // 0x4C 'L'
+ {247, 8, 9, 10, 1, -8}, // 0x4D 'M'
+ {256, 7, 9, 9, 1, -8}, // 0x4E 'N'
+ {264, 9, 9, 9, 0, -8}, // 0x4F 'O'
+ {275, 6, 9, 8, 1, -8}, // 0x50 'P'
+ {282, 9, 9, 9, 0, -8}, // 0x51 'Q'
+ {293, 7, 9, 9, 1, -8}, // 0x52 'R'
+ {301, 6, 9, 8, 1, -8}, // 0x53 'S'
+ {308, 7, 9, 7, 0, -8}, // 0x54 'T'
+ {316, 7, 9, 9, 1, -8}, // 0x55 'U'
+ {324, 8, 9, 8, 0, -8}, // 0x56 'V'
+ {333, 11, 9, 11, 0, -8}, // 0x57 'W'
+ {346, 6, 9, 8, 1, -8}, // 0x58 'X'
+ {353, 8, 9, 8, 0, -8}, // 0x59 'Y'
+ {362, 7, 9, 7, 0, -8}, // 0x5A 'Z'
+ {370, 2, 12, 3, 1, -8}, // 0x5B '['
+ {373, 3, 9, 3, 0, -8}, // 0x5C '\'
+ {377, 3, 12, 3, 0, -8}, // 0x5D ']'
+ {382, 4, 5, 6, 1, -8}, // 0x5E '^'
+ {385, 6, 1, 7, 0, 2}, // 0x5F '_'
+ {386, 2, 2, 4, 1, -8}, // 0x60 '`'
+ {387, 5, 6, 7, 1, -5}, // 0x61 'a'
+ {391, 5, 9, 7, 1, -8}, // 0x62 'b'
+ {397, 6, 6, 6, 0, -5}, // 0x63 'c'
+ {402, 6, 9, 7, 0, -8}, // 0x64 'd'
+ {409, 5, 6, 7, 1, -5}, // 0x65 'e'
+ {413, 3, 9, 3, 0, -8}, // 0x66 'f'
+ {417, 6, 9, 7, 0, -5}, // 0x67 'g'
+ {424, 5, 9, 7, 1, -8}, // 0x68 'h'
+ {430, 1, 9, 3, 1, -8}, // 0x69 'i'
+ {432, 2, 12, 3, 0, -8}, // 0x6A 'j'
+ {435, 5, 9, 6, 1, -8}, // 0x6B 'k'
+ {441, 1, 9, 3, 1, -8}, // 0x6C 'l'
+ {443, 8, 6, 10, 1, -5}, // 0x6D 'm'
+ {449, 5, 6, 7, 1, -5}, // 0x6E 'n'
+ {453, 6, 6, 7, 0, -5}, // 0x6F 'o'
+ {458, 5, 9, 7, 1, -5}, // 0x70 'p'
+ {464, 6, 9, 7, 0, -5}, // 0x71 'q'
+ {471, 3, 6, 4, 1, -5}, // 0x72 'r'
+ {474, 6, 6, 6, 0, -5}, // 0x73 's'
+ {479, 3, 8, 3, 0, -7}, // 0x74 't'
+ {482, 5, 6, 7, 1, -5}, // 0x75 'u'
+ {486, 6, 6, 6, 0, -5}, // 0x76 'v'
+ {491, 8, 6, 9, 0, -5}, // 0x77 'w'
+ {497, 4, 6, 6, 1, -5}, // 0x78 'x'
+ {500, 5, 9, 6, 0, -5}, // 0x79 'y'
+ {506, 5, 6, 6, 0, -5}, // 0x7A 'z'
+ {510, 2, 12, 4, 1, -8}, // 0x7B '{'
+ {513, 1, 12, 3, 1, -8}, // 0x7C '|'
+ {515, 3, 12, 4, 0, -8}, // 0x7D '}'
+ {520, 5, 2, 7, 1, -4}, // 0x7E '~'
+ {522, 6, 9, 8, 1, -8}, //
+ {529, 9, 11, 9, 0, -8}, //
+ {542, 6, 11, 7, 1, -10}, //
+ {551, 0, 0, 8, 0, 0}, //
+ {551, 4, 9, 5, 1, -8}, //
+ {556, 0, 0, 8, 0, 0}, //
+ {556, 0, 0, 8, 0, 0}, //
+ {556, 0, 0, 8, 0, 0}, //
+ {556, 0, 0, 8, 0, 0}, //
+ {556, 6, 8, 8, 1, -7}, //
+ {562, 0, 0, 8, 0, 0}, //
+ {562, 11, 9, 13, 1, -8}, //
+ {575, 0, 0, 8, 0, 0}, //
+ {575, 11, 9, 12, 1, -8}, //
+ {588, 6, 11, 8, 1, -10}, //
+ {597, 9, 9, 9, 0, -8}, //
+ {608, 7, 11, 9, 1, -8}, //
+ {618, 6, 11, 7, 0, -8}, //
+ {627, 0, 0, 8, 0, 0}, //
+ {627, 0, 0, 8, 0, 0}, //
+ {627, 0, 0, 8, 0, 0}, //
+ {627, 0, 0, 8, 0, 0}, //
+ {627, 0, 0, 8, 0, 0}, //
+ {627, 0, 0, 8, 0, 0}, //
+ {627, 0, 0, 8, 0, 0}, //
+ {627, 0, 0, 8, 0, 0}, //
+ {627, 0, 0, 8, 0, 0}, //
+ {627, 9, 6, 10, 0, -5}, //
+ {634, 0, 0, 8, 0, 0}, //
+ {634, 9, 6, 10, 1, -5}, //
+ {641, 4, 8, 6, 1, -7}, //
+ {645, 6, 9, 7, 0, -8}, //
+ {652, 5, 7, 7, 1, -5}, //
+ {657, 0, 0, 8, 0, 0}, //
+ {657, 7, 11, 7, 0, -10}, //
+ {667, 5, 11, 6, 0, -7}, //
+ {674, 5, 9, 6, 0, -8}, //
+ {680, 0, 0, 8, 0, 0}, //
+ {680, 6, 10, 7, 1, -9}, //
+ {688, 0, 0, 8, 0, 0}, //
+ {688, 0, 0, 8, 0, 0}, //
+ {688, 6, 11, 8, 1, -10}, //
+ {697, 7, 9, 9, 1, -8}, //
+ {705, 0, 0, 8, 0, 0}, //
+ {705, 0, 0, 8, 0, 0}, //
+ {705, 2, 12, 3, 0, -8}, //
+ {708, 0, 0, 8, 0, 0}, //
+ {708, 0, 0, 8, 0, 0}, //
+ {708, 3, 11, 3, 0, -10}, //
+ {713, 0, 0, 8, 0, 0}, //
+ {713, 0, 0, 8, 0, 0}, //
+ {713, 1, 9, 3, 1, -8}, //
+ {715, 1, 9, 3, 1, -8}, //
+ {717, 3, 8, 5, 1, -7}, //
+ {720, 6, 9, 7, 1, -5}, //
+ {727, 0, 0, 8, 0, 0}, //
+ {727, 0, 0, 8, 0, 0}, //
+ {727, 6, 9, 7, 0, -8}, //
+ {734, 9, 9, 11, 1, -8}, //
+ {745, 6, 6, 6, 0, -5}, //
+ {750, 0, 0, 8, 0, 0}, //
+ {750, 0, 0, 8, 0, 0}, //
+ {750, 6, 9, 8, 1, -8}, //
+ {757, 6, 6, 6, 0, -5}, //
+ {762, 3, 9, 3, 0, -8}, //
+ {766, 8, 9, 8, 0, -8}, //
+ {775, 6, 9, 8, 1, -8}, //
+ {782, 6, 9, 8, 1, -8}, //
+ {789, 6, 9, 7, 1, -8}, //
+ {796, 9, 11, 10, 0, -8}, //
+ {809, 6, 9, 8, 1, -8}, //
+ {816, 9, 9, 11, 1, -8}, //
+ {827, 6, 9, 8, 1, -8}, //
+ {834, 7, 9, 9, 1, -8}, //
+ {842, 7, 11, 9, 1, -10}, //
+ {852, 6, 9, 8, 1, -8}, //
+ {859, 7, 9, 8, 0, -8}, //
+ {867, 8, 9, 10, 1, -8}, //
+ {876, 7, 9, 9, 1, -8}, //
+ {884, 8, 9, 10, 1, -8}, //
+ {893, 7, 9, 9, 1, -8}, //
+ {901, 6, 9, 8, 1, -8}, //
+ {908, 7, 9, 9, 1, -8}, //
+ {916, 7, 9, 7, 0, -8}, //
+ {924, 7, 9, 7, 0, -8}, //
+ {932, 9, 9, 10, 1, -8}, //
+ {943, 6, 9, 8, 1, -8}, //
+ {950, 8, 11, 9, 1, -8}, //
+ {961, 6, 9, 8, 1, -8}, //
+ {968, 8, 9, 10, 1, -8}, //
+ {977, 9, 11, 10, 1, -8}, //
+ {990, 10, 9, 10, 0, -8}, //
+ {1002, 9, 9, 10, 1, -8}, //
+ {1013, 6, 9, 8, 1, -8}, //
+ {1020, 7, 9, 9, 1, -8}, //
+ {1028, 10, 9, 12, 1, -8}, //
+ {1040, 6, 9, 8, 1, -8}, //
+ {1047, 6, 6, 7, 0, -5}, //
+ {1052, 6, 9, 7, 0, -8}, //
+ {1059, 5, 6, 6, 1, -5}, //
+ {1063, 4, 6, 5, 1, -5}, //
+ {1066, 7, 7, 7, 0, -5}, //
+ {1073, 6, 6, 7, 0, -5}, //
+ {1078, 8, 6, 9, 1, -5}, //
+ {1084, 6, 6, 6, 0, -5}, //
+ {1089, 5, 6, 7, 1, -5}, //
+ {1093, 5, 8, 7, 1, -7}, //
+ {1098, 4, 6, 6, 1, -5}, //
+ {1101, 5, 6, 6, 0, -5}, //
+ {1105, 6, 6, 7, 1, -5}, //
+ {1110, 5, 6, 7, 1, -5}, //
+ {1114, 6, 6, 7, 0, -5}, //
+ {1119, 5, 6, 7, 1, -5}, //
+ {1123, 5, 9, 7, 1, -5}, //
+ {1129, 6, 6, 6, 0, -5}, //
+ {1134, 5, 6, 5, 0, -5}, //
+ {1138, 5, 9, 6, 0, -5}, //
+ {1144, 10, 11, 10, 0, -7}, //
+ {1158, 5, 6, 6, 0, -5}, //
+ {1162, 6, 7, 7, 1, -5}, //
+ {1168, 4, 6, 6, 1, -5}, //
+ {1171, 6, 6, 8, 1, -5}, //
+ {1176, 7, 7, 9, 1, -5}, //
+ {1183, 7, 6, 8, 0, -5}, //
+ {1189, 6, 6, 8, 1, -5}, //
+ {1194, 5, 6, 6, 1, -5}, //
+ {1198, 5, 6, 6, 1, -5}, //
+ {1202, 8, 6, 9, 1, -5}, //
+ {1208, 5, 6, 7, 1, -5} //
+};
+
+const GFXfont FreeSans6pt8bCyrillic PROGMEM = {(uint8_t *)FreeSans6pt8bCyrillicBitmaps, (GFXglyph *)FreeSans6pt8bCyrillicGlyphs,
+ 0x20, 0xFF, 16};
diff --git a/src/graphics/niche/Fonts/README.md b/src/graphics/niche/Fonts/README.md
new file mode 100644
index 000000000..e79927786
--- /dev/null
+++ b/src/graphics/niche/Fonts/README.md
@@ -0,0 +1,4 @@
+# NicheGraphics - Fonts
+
+A common area to store fonts which might be reused by different Niche Graphics UIs
+In future, we may want to separate these by library (AdafruitGFX, u8g2, etc)
diff --git a/src/graphics/niche/InkHUD/Applet.cpp b/src/graphics/niche/InkHUD/Applet.cpp
new file mode 100644
index 000000000..ebd0acc78
--- /dev/null
+++ b/src/graphics/niche/InkHUD/Applet.cpp
@@ -0,0 +1,843 @@
+#ifdef MESHTASTIC_INCLUDE_INKHUD
+
+#include "./Applet.h"
+
+#include "RTC.h"
+
+using namespace NicheGraphics;
+
+InkHUD::AppletFont InkHUD::Applet::fontLarge; // General purpose font. Set by setDefaultFonts
+InkHUD::AppletFont InkHUD::Applet::fontSmall; // General purpose font. Set by setDefaultFonts
+constexpr float InkHUD::Applet::LOGO_ASPECT_RATIO; // Ratio of the Meshtastic logo
+
+InkHUD::Applet::Applet() : GFX(0, 0)
+{
+ // GFX is given initial dimensions of 0
+ // The width and height will change dynamically, depending on Applet tiling
+ // If you're getting a "divide by zero error", consider it an assert:
+ // WindowManager should be the only one controlling the rendering
+}
+
+// The raw pixel output generated by AdafruitGFX drawing
+// Hand off to the applet's tile, which will in-turn pass to the window manager
+void InkHUD::Applet::drawPixel(int16_t x, int16_t y, uint16_t color)
+{
+ // Only render pixels if they fall within user's cropped region
+ if (x >= cropLeft && x < (cropLeft + cropWidth) && y >= cropTop && y < (cropTop + cropHeight))
+ assignedTile->handleAppletPixel(x, y, (Color)color);
+}
+
+// Sets which tile the applet renders for
+// Pixel output is passed to tile during render()
+// This should only be called by Tile::assignApplet
+void InkHUD::Applet::setTile(Tile *t)
+{
+ // If we're setting (not clearing), make sure the link is "reciprocal"
+ if (t)
+ assert(t->getAssignedApplet() == this);
+
+ assignedTile = t;
+}
+
+// Which tile will the applet render() to?
+InkHUD::Tile *InkHUD::Applet::getTile()
+{
+ return assignedTile;
+}
+
+void InkHUD::Applet::render()
+{
+ assert(assignedTile); // Ensure that we have a tile
+ assert(assignedTile->getAssignedApplet() == this); // Ensure that we have a reciprocal link with the tile
+
+ wantRender = false; // Clear the flag set by requestUpdate
+ wantAutoshow = false; // If we're rendering now, it means our request was considered. It may or may not have been granted.
+ wantUpdateType = Drivers::EInk::UpdateTypes::UNSPECIFIED; // Our requested type has been considered by now. Tidy up.
+
+ updateDimensions();
+ resetDrawingSpace();
+ onRender(); // Derived applet's drawing takes place here
+
+ // If our tile is (or was) highlighted, to indicate a change in focus
+ if (Tile::highlightTarget == assignedTile) {
+ // Draw the highlight
+ if (!Tile::highlightShown) {
+ drawRect(0, 0, width(), height(), BLACK);
+ Tile::startHighlightTimeout();
+ Tile::highlightShown = true;
+ }
+
+ // Clear the highlight
+ else {
+ Tile::cancelHighlightTimeout();
+ Tile::highlightShown = false;
+ Tile::highlightTarget = nullptr;
+ }
+ }
+}
+
+// Does the applet want to render now?
+// Checks whether the applet called requestUpdate() recently, in response to an event
+bool InkHUD::Applet::wantsToRender()
+{
+ return wantRender;
+}
+
+// Does the applet want to be moved to foreground before next render, to show new data?
+// User specifies whether an applet has permission for this, using the on-screen menu
+bool InkHUD::Applet::wantsToAutoshow()
+{
+ return wantAutoshow;
+}
+
+// Which technique would this applet prefer that the display use to change the image?
+Drivers::EInk::UpdateTypes InkHUD::Applet::wantsUpdateType()
+{
+ return wantUpdateType;
+}
+
+// Get size of the applet's drawing space from its tile
+void InkHUD::Applet::updateDimensions()
+{
+ assert(assignedTile);
+ WIDTH = assignedTile->getWidth();
+ HEIGHT = assignedTile->getHeight();
+ _width = WIDTH;
+ _height = HEIGHT;
+}
+
+// Ensure that render() always starts with the same initial drawing config
+void InkHUD::Applet::resetDrawingSpace()
+{
+ resetCrop(); // Allow pixel from any region of the applet to draw
+ setTextColor(BLACK); // Reset text params
+ setCursor(0, 0);
+ setTextWrap(false);
+ setFont(AppletFont()); // Restore the default AdafruitGFX font
+}
+
+// Tell the window manager that we want to render now
+// Applets should internally listen for events they are interested in, via MeshModule, CallbackObserver etc
+// When an applet decides it has heard something important, and wants to redraw, it calls this method
+// Once the window manager has given other applets a chance to process whatever event we just detected,
+// it will run Applet::render(), which may draw our applet to screen, if it is shown (forgeround)
+void InkHUD::Applet::requestUpdate(Drivers::EInk::UpdateTypes type)
+{
+ wantRender = true;
+ wantUpdateType = type;
+ WindowManager::getInstance()->requestUpdate();
+}
+
+// Ask window manager to move this applet to foreground at start of next render
+// Users select which applets have permission for this using the on-screen menu
+void InkHUD::Applet::requestAutoshow()
+{
+ wantAutoshow = true;
+}
+
+// Called when an Applet begins running
+// Active applets are considered "enabled"
+// They should now listen for events, and request their own updates
+// They may also be force rendered by the window manager at any time
+// Applets can be activated at run-time through the on-screen menu
+void InkHUD::Applet::activate()
+{
+ onActivate(); // Call derived class' handler
+ active = true;
+}
+
+// Called when an Applet stop running
+// Inactive applets are considered "disabled"
+// They should not listen for events, process data
+// They will not be rendered
+// Applets can be deactivated at run-time through the on-screen menu
+void InkHUD::Applet::deactivate()
+{
+ // If applet is still in foreground, run its onBackground code first
+ if (isForeground())
+ sendToBackground();
+
+ // If applet is active, run its onDeactivate code first
+ if (isActive())
+ onDeactivate(); // Derived class' handler
+ active = false;
+}
+
+// Is the Applet running?
+// Note: active / inactive is not related to background / foreground
+// An inactive applet is *fully* disabled
+bool InkHUD::Applet::isActive()
+{
+ return active;
+}
+
+// Begin showing the Applet
+// It will be rendered immediately to whichever tile it is assigned
+// The window manager will also now honor requestUpdate() calls from this applet
+void InkHUD::Applet::bringToForeground()
+{
+ if (!foreground) {
+ foreground = true;
+ onForeground(); // Run derived applet class' handler
+ }
+
+ requestUpdate();
+}
+
+// Stop showing the Applet
+// Calls to requestUpdate() will no longer be honored
+// When one applet moves to background, another should move to foreground
+void InkHUD::Applet::sendToBackground()
+{
+ if (foreground) {
+ foreground = false;
+ onBackground(); // Run derived applet class' handler
+ }
+}
+
+// Is the applet currently displayed on a tile
+bool InkHUD::Applet::isForeground()
+{
+ return foreground;
+}
+
+// Limit drawing to a certain region of the applet
+// Pixels outside this region will be discarded
+void InkHUD::Applet::setCrop(int16_t left, int16_t top, uint16_t width, uint16_t height)
+{
+ cropLeft = left;
+ cropTop = top;
+ cropWidth = width;
+ cropHeight = height;
+}
+
+// Allow drawing to any region of the Applet
+// Reverses Applet::setCrop
+void InkHUD::Applet::resetCrop()
+{
+ setCrop(0, 0, width(), height());
+}
+
+// Convert relative width to absolute width, in px
+// X(0) is 0
+// X(0.5) is width() / 2
+// X(1) is width()
+uint16_t InkHUD::Applet::X(float f)
+{
+ return width() * f;
+}
+
+// Convert relative hight to absolute height, in px
+// Y(0) is 0
+// Y(0.5) is height() / 2
+// Y(1) is height()
+uint16_t InkHUD::Applet::Y(float f)
+{
+ return height() * f;
+}
+
+// Print text, specifying the position of any edge / corner of the textbox
+void InkHUD::Applet::printAt(int16_t x, int16_t y, const char *text, HorizontalAlignment ha, VerticalAlignment va)
+{
+ printAt(x, y, std::string(text), ha, va);
+}
+
+// Print text, specifying the position of any edge / corner of the textbox
+void InkHUD::Applet::printAt(int16_t x, int16_t y, std::string text, HorizontalAlignment ha, VerticalAlignment va)
+{
+ // Custom font
+ // - set with AppletFont::addSubstitution
+ // - find certain UTF8 chars
+ // - replace with glpyh from custom font (or suitable ASCII addSubstitution?)
+ getFont().applySubstitutions(&text);
+
+ // We do still have to run getTextBounds to find the width
+ int16_t textOffsetX, textOffsetY;
+ uint16_t textWidth, textHeight;
+ getTextBounds(text.c_str(), 0, 0, &textOffsetX, &textOffsetY, &textWidth, &textHeight);
+
+ int16_t cursorX = 0;
+ int16_t cursorY = 0;
+
+ switch (ha) {
+ case LEFT:
+ cursorX = x - textOffsetX;
+ break;
+ case CENTER:
+ cursorX = (x - textOffsetX) - (textWidth / 2);
+ break;
+ case RIGHT:
+ cursorX = (x - textOffsetX) - textWidth;
+ break;
+ }
+
+ // We're using a fixed line height (getFontDimensions), rather than sizing to text (getTextBounds)
+ // Note: the FontDimensions values for this are unsigned
+
+ switch (va) {
+ case TOP:
+ cursorY = y + currentFont.heightAboveCursor();
+ break;
+ case MIDDLE:
+ cursorY = (y + currentFont.heightAboveCursor()) - (currentFont.lineHeight() / 2);
+ break;
+ case BOTTOM:
+ cursorY = (y + currentFont.heightAboveCursor()) - currentFont.lineHeight();
+ break;
+ }
+
+ setCursor(cursorX, cursorY);
+ print(text.c_str());
+}
+
+// Set which font should be used for subsequent drawing
+// This is AppletFont type, which is a wrapper for AdfruitGFX font, with some precalculated dimension data
+void InkHUD::Applet::setFont(AppletFont f)
+{
+ GFX::setFont(f.gfxFont);
+ currentFont = f;
+}
+
+// Get which font is currently being used for drawing
+// This is AppletFont type, which is a wrapper for AdfruitGFX font, with some precalculated dimension data
+InkHUD::AppletFont InkHUD::Applet::getFont()
+{
+ return currentFont;
+}
+
+// Set two general-purpose fonts, which are reused by many applets
+// Applets are also permitted to use other fonts, if they can justify the flash usage
+void InkHUD::Applet::setDefaultFonts(AppletFont large, AppletFont small)
+{
+ Applet::fontSmall = small;
+ Applet::fontLarge = large;
+}
+
+// Gets rendered width of a string
+// Wrapper for getTextBounds
+uint16_t InkHUD::Applet::getTextWidth(const char *text)
+{
+
+ // We do still have to run getTextBounds to find the width
+ int16_t textOffsetX, textOffsetY;
+ uint16_t textWidth, textHeight;
+ getTextBounds(text, 0, 0, &textOffsetX, &textOffsetY, &textWidth, &textHeight);
+
+ return textWidth;
+}
+
+// Gets rendered width of a string
+// Wrappe for getTextBounds
+uint16_t InkHUD::Applet::getTextWidth(std::string text)
+{
+ getFont().applySubstitutions(&text);
+
+ return getTextWidth(text.c_str());
+}
+
+// Evaluate SNR and RSSI to qualify signal strength at one of four discrete levels
+// Roughly comparable to values used by the iOS app;
+// I didn't actually go look up the code, just fit to a sample graphic I have of the iOS signal indicator
+InkHUD::SignalStrength InkHUD::Applet::getSignalStrength(float snr, float rssi)
+{
+ uint8_t score = 0;
+
+ // Give a score for the SNR
+ if (snr > -17.5)
+ score += 2;
+ else if (snr > -26.0)
+ score += 1;
+
+ // Give a score for the RSSI
+ if (rssi > -115.0)
+ score += 3;
+ else if (rssi > -120.0)
+ score += 2;
+ else if (rssi > -126.0)
+ score += 1;
+
+ // Combine scores, then give a result
+ if (score >= 5)
+ return SIGNAL_GOOD;
+ else if (score >= 4)
+ return SIGNAL_FAIR;
+ else if (score > 0)
+ return SIGNAL_BAD;
+ else
+ return SIGNAL_NONE;
+}
+
+// Apply the standard "node id" formatting to a nodenum int: !0123abdc
+std::string InkHUD::Applet::hexifyNodeNum(NodeNum num)
+{
+ // Not found in nodeDB, show a hex nodeid instead
+ char nodeIdHex[10];
+ sprintf(nodeIdHex, "!%0x", num); // Convert to the typical "fixed width hex with !" format
+ return std::string(nodeIdHex);
+}
+
+void InkHUD::Applet::printWrapped(int16_t left, int16_t top, uint16_t width, std::string text)
+{
+ // Custom font glyphs
+ // - set with AppletFont::addSubstitution
+ // - find certain UTF8 chars
+ // - replace with glpyh from custom font (or suitable ASCII addSubstitution?)
+ getFont().applySubstitutions(&text);
+
+ // Place the AdafruitGFX cursor to suit our "top" coord
+ setCursor(left, top + getFont().heightAboveCursor());
+
+ // How wide a space character is
+ // Used when simulating print, for dimensioning
+ // Works around issues where getTextDimensions() doesn't account for whitespace
+ const uint8_t wSp = getFont().widthBetweenWords();
+
+ // Move through our text, character by character
+ uint16_t wordStart = 0;
+ for (uint16_t i = 0; i < text.length(); i++) {
+
+ // Found: end of word (split by spaces or newline)
+ // Also handles end of string
+ if (text[i] == ' ' || text[i] == '\n' || i == text.length() - 1) {
+ // Isolate this word
+ uint16_t wordLength = (i - wordStart) + 1; // Plus one. Imagine: "a". End - Start is 0, but length is 1
+ std::string word = text.substr(wordStart, wordLength);
+ wordStart = i + 1; // Next word starts *after* the space
+
+ // If word is terminated by a newline char, don't actually print it.
+ // We'll manually add a new line later
+ if (word.back() == '\n')
+ word.pop_back();
+
+ // Measure the word, in px
+ int16_t l, t;
+ uint16_t w, h;
+ getTextBounds(word.c_str(), getCursorX(), getCursorY(), &l, &t, &w, &h);
+
+ // Word is short
+ if (w < width) {
+ // Word fits on current line
+ if ((l + w + wSp) < left + width)
+ print(word.c_str());
+
+ // Word doesn't fit on current line
+ else {
+ setCursor(left, getCursorY() + getFont().lineHeight()); // Newline
+ print(word.c_str());
+ }
+ }
+
+ // Word is really long
+ // (wider than applet)
+ else {
+ // Horribly inefficient:
+ // Rather than working directly with the glyph sizes,
+ // we're going to run everything through getTextBounds as a c-string of length 1
+ // This is because AdafruitGFX has special internal handling for their legacy 6x8 font,
+ // which would be a pain to add manually here.
+ // These super-long strings probably don't come up often so we can maybe tolerate this.
+
+ // Todo: rewrite making use of AdafruitGFX native text wrapping
+ char cstr[] = {0, 0};
+ int16_t l, t;
+ uint16_t w, h;
+ for (uint16_t c = 0; c < word.length(); c++) {
+ // Shove next char into a c string
+ cstr[0] = word[c];
+ getTextBounds(cstr, getCursorX(), getCursorY(), &l, &t, &w, &h);
+
+ // Manual newline, if next character will spill beyond screen edge
+ if ((l + w) > left + width)
+ setCursor(left, getCursorY() + getFont().lineHeight());
+
+ // Print next character
+ print(word[c]);
+ }
+ }
+ }
+
+ // If word was terminated by a newline char, manually add the new line now
+ if (text[i] == '\n') {
+ setCursor(left, getCursorY() + getFont().lineHeight()); // Manual newline
+ wordStart = i + 1; // New word begins after the newline. Otherwise print will add an *extra* line
+ }
+ }
+}
+
+// Simulate running printWrapped, to determine how tall the block of text will be.
+// This is a wasteful way of handling things. Maybe some way to optimize in future?
+uint32_t InkHUD::Applet::getWrappedTextHeight(int16_t left, uint16_t width, std::string text)
+{
+ // Cache the current crop region
+ int16_t cL = cropLeft;
+ int16_t cT = cropTop;
+ uint16_t cW = cropWidth;
+ uint16_t cH = cropHeight;
+
+ setCrop(-1, -1, 0, 0); // Set crop to temporarily discard all pixels
+ printWrapped(left, 0, width, text); // Simulate only - no pixels drawn
+
+ // Restore previous crop region
+ cropLeft = cL;
+ cropTop = cT;
+ cropWidth = cW;
+ cropHeight = cH;
+
+ // Note: printWrapped() offsets the initial cursor position by heightAboveCursor() val,
+ // so we need to account for that when determining the height
+ return (getCursorY() + getFont().heightBelowCursor());
+}
+
+// Fill a region with sparse diagonal lines, to create a pseudo-translucent fill
+void InkHUD::Applet::hatchRegion(int16_t x, int16_t y, uint16_t w, uint16_t h, uint8_t spacing, Color color)
+{
+ // Cache the currently cropped region
+ int16_t oldCropL = cropLeft;
+ int16_t oldCropT = cropTop;
+ uint16_t oldCropW = cropWidth;
+ uint16_t oldCropH = cropHeight;
+
+ setCrop(x, y, w, h);
+
+ // Draw lines starting along the top edge, every few px
+ for (int16_t ix = x; ix < x + w; ix += spacing) {
+ for (int16_t i = 0; i < w || i < h; i++) {
+ drawPixel(ix + i, y + i, color);
+ }
+ }
+
+ // Draw lines starting along the left edge, every few px
+ for (int16_t iy = y; iy < y + h; iy += spacing) {
+ for (int16_t i = 0; i < w || i < h; i++) {
+ drawPixel(x + i, iy + i, color);
+ }
+ }
+
+ // Restore any previous crop
+ // If none was set, this will clear
+ cropLeft = oldCropL;
+ cropTop = oldCropT;
+ cropWidth = oldCropW;
+ cropHeight = oldCropH;
+}
+
+// Get a human readable time representation of an epoch time (seconds since 1970)
+// If time is invalid, this will be an empty string
+std::string InkHUD::Applet::getTimeString(uint32_t epochSeconds)
+{
+#ifdef BUILD_EPOCH
+ constexpr uint32_t validAfterEpoch = BUILD_EPOCH - (SEC_PER_DAY * 30 * 6); // 6 Months prior to build
+#else
+ constexpr uint32_t validAfterEpoch = 1727740800 - (SEC_PER_DAY * 30 * 6); // 6 Months prior to October 1, 2024 12:00:00 AM GMT
+#endif
+
+ uint32_t epochNow = getValidTime(RTCQuality::RTCQualityDevice, true);
+
+ int32_t daysAgo = (epochNow - epochSeconds) / SEC_PER_DAY;
+ int32_t hoursAgo = (epochNow - epochSeconds) / SEC_PER_HOUR;
+
+ // Times are invalid: rtc is much older than when code was built
+ // Don't give any human readable string
+ if (epochNow <= validAfterEpoch) {
+ LOG_DEBUG("RTC prior to buildtime");
+ return "";
+ }
+
+ // Times are invalid: argument time is significantly ahead of RTC
+ // Don't give any human readable string
+ if (daysAgo < -2) {
+ LOG_DEBUG("RTC in future");
+ return "";
+ }
+
+ // Times are probably invalid: more than 6 months ago
+ if (daysAgo > 6 * 30) {
+ LOG_DEBUG("RTC val > 6 months old");
+ return "";
+ }
+
+ if (daysAgo > 1)
+ return to_string(daysAgo) + " days ago";
+
+ else if (hoursAgo > 18)
+ return "Yesterday";
+
+ else {
+
+ uint32_t hms = epochSeconds % SEC_PER_DAY;
+ hms = (hms + SEC_PER_DAY) % SEC_PER_DAY;
+
+ // Tear apart hms into h:m
+ uint32_t hour = hms / SEC_PER_HOUR;
+ uint32_t min = (hms % SEC_PER_HOUR) / SEC_PER_MIN;
+
+ // Format the clock string
+ char clockStr[11];
+ sprintf(clockStr, "%u:%02u %s", (hour % 12 == 0 ? 12 : hour % 12), min, hour > 11 ? "PM" : "AM");
+
+ return clockStr;
+ }
+}
+
+// If no argument specified, get time string for the current RTC time
+std::string InkHUD::Applet::getTimeString()
+{
+ return getTimeString(getValidTime(RTCQuality::RTCQualityDevice, true));
+}
+
+// Calculate how many nodes have been seen within our preferred window of activity
+// This period is set by user, via the menu
+// Todo: optimize to calculate once only per WindowManager::render
+uint16_t InkHUD::Applet::getActiveNodeCount()
+{
+ // Don't even try to count nodes if RTC isn't set
+ // The last heard values in nodedb will be incomprehensible
+ if (getRTCQuality() == RTCQualityNone)
+ return 0;
+
+ uint16_t count = 0;
+
+ // For each node in db
+ for (uint16_t i = 0; i < nodeDB->getNumMeshNodes(); i++) {
+ meshtastic_NodeInfoLite *node = nodeDB->getMeshNodeByIndex(i);
+
+ // Check if heard recently, and not our own node
+ if (sinceLastSeen(node) < settings.recentlyActiveSeconds && node->num != nodeDB->getNodeNum())
+ count++;
+ }
+
+ return count;
+}
+
+// Get an abbreviated, human readable, distance string
+// Honors config.display.units, to offer both metric and imperial
+std::string InkHUD::Applet::localizeDistance(uint32_t meters)
+{
+ constexpr float FEET_PER_METER = 3.28084;
+ constexpr uint16_t FEET_PER_MILE = 5280;
+
+ // Resulting string
+ std::string localized;
+
+ // Imeperial
+ if (config.display.units == meshtastic_Config_DisplayConfig_DisplayUnits_IMPERIAL) {
+ uint32_t feet = meters * FEET_PER_METER;
+ // Distant (miles, rounded)
+ if (feet > FEET_PER_MILE / 2) {
+ localized += to_string((uint32_t)roundf(feet / FEET_PER_MILE));
+ localized += "mi";
+ }
+ // Nearby (feet)
+ else {
+ localized += to_string(feet);
+ localized += "ft";
+ }
+ }
+
+ // Metric
+ else {
+ // Distant (kilometers, rounded)
+ if (meters >= 500) {
+ localized += to_string((uint32_t)roundf(meters / 1000.0));
+ localized += "km";
+ }
+ // Nearby (meters)
+ else {
+ localized += to_string(meters);
+ localized += "m";
+ }
+ }
+
+ return localized;
+}
+
+void InkHUD::Applet::printThick(int16_t xCenter, int16_t yCenter, std::string text, uint8_t thicknessX, uint8_t thicknessY)
+{
+ // How many times to draw along x axis
+ int16_t xStart;
+ int16_t xEnd;
+ switch (thicknessX) {
+ case 0:
+ assert(false);
+ case 1:
+ xStart = xCenter;
+ xEnd = xCenter;
+ break;
+ case 2:
+ xStart = xCenter;
+ xEnd = xCenter + 1;
+ break;
+ default:
+ xStart = xCenter - (thicknessX / 2);
+ xEnd = xCenter + (thicknessX / 2);
+ }
+
+ // How many times to draw along Y axis
+ int16_t yStart;
+ int16_t yEnd;
+ switch (thicknessY) {
+ case 0:
+ assert(false);
+ case 1:
+ yStart = yCenter;
+ yEnd = yCenter;
+ break;
+ case 2:
+ yStart = yCenter;
+ yEnd = yCenter + 1;
+ break;
+ default:
+ yStart = yCenter - (thicknessY / 2);
+ yEnd = yCenter + (thicknessY / 2);
+ }
+
+ // Print multiple times, overlapping
+ for (int16_t x = xStart; x <= xEnd; x++) {
+ for (int16_t y = yStart; y <= yEnd; y++) {
+ printAt(x, y, text, CENTER, MIDDLE);
+ }
+ }
+}
+
+// Allow this applet to suppress notifications
+// Asked before a notification is shown via the NotificationApplet
+// An applet might want to suppress a notification if the applet itself already displays this info
+// Example: AllMessageApplet should not approve notifications for messages, if it is in foreground
+bool InkHUD::Applet::approveNotification(InkHUD::Notification &n)
+{
+ // By default, no objection
+ return true;
+}
+
+// Draw the standard header, used by most Applets
+void InkHUD::Applet::drawHeader(std::string text)
+{
+ setFont(fontSmall);
+
+ // Y position for divider
+ // - between header text and messages
+ constexpr int16_t padDivH = 2;
+ const int16_t headerDivY = padDivH + fontSmall.lineHeight() + padDivH - 1;
+
+ // Print header
+ printAt(0, padDivH, text);
+
+ // Divider
+ // - below header text: separates message
+ // - above header text: separates other applets
+ for (int16_t x = 0; x < width(); x += 2) {
+ drawPixel(x, 0, BLACK);
+ drawPixel(x, headerDivY, BLACK); // Dotted 50%
+ }
+}
+
+// Get the height of the standard applet header
+// This will vary, depending on font
+// Applets use this value to avoid drawing overtop the header
+uint16_t InkHUD::Applet::getHeaderHeight()
+{
+ // Y position for divider
+ // - between header text and messages
+ constexpr int16_t padDivH = 2;
+ const int16_t headerDivY = padDivH + fontSmall.lineHeight() + padDivH - 1;
+
+ return headerDivY + 1; // "Plus one": height is always one more than Y position
+}
+
+// "Scale to fit": width of Meshtastic logo to fit given region, maintaining aspect ratio
+uint16_t InkHUD::Applet::getLogoWidth(uint16_t limitWidth, uint16_t limitHeight)
+{
+ // Determine whether we're limited by width or height
+ // Makes sure we draw the logo as large as possible, within the specified region,
+ // while still maintaining correct aspect ratio
+ if (limitWidth > limitHeight * LOGO_ASPECT_RATIO)
+ return limitHeight * LOGO_ASPECT_RATIO;
+ else
+ return limitWidth;
+}
+
+// "Scale to fit": height of Meshtastic logo to fit given region, maintaining aspect ratio
+uint16_t InkHUD::Applet::getLogoHeight(uint16_t limitWidth, uint16_t limitHeight)
+{
+ // Determine whether we're limited by width or height
+ // Makes sure we draw the logo as large as possible, within the specified region,
+ // while still maintaining correct aspect ratio
+ if (limitHeight > limitWidth / LOGO_ASPECT_RATIO)
+ return limitWidth / LOGO_ASPECT_RATIO;
+ else
+ return limitHeight;
+}
+
+// Draw a scalable Meshtastic logo
+// Make sure to provide dimensions which have the correct aspect ratio (~2)
+// Three paths, drawn thick using quads, with one corner "radiused"
+void InkHUD::Applet::drawLogo(int16_t centerX, int16_t centerY, uint16_t width, uint16_t height)
+{
+ struct Point {
+ int x;
+ int y;
+ };
+ typedef Point Distance;
+
+ int16_t logoTh = width * 0.068; // Thickness scales with width. Measured from logo at meshtastic.org.
+ int16_t logoL = centerX - (width / 2) + (logoTh / 2);
+ int16_t logoT = centerY - (height / 2) + (logoTh / 2);
+ int16_t logoW = width - logoTh;
+ int16_t logoH = height - logoTh;
+ int16_t logoR = logoL + logoW - 1;
+ int16_t logoB = logoT + logoH - 1;
+
+ // Points for paths (a, b, and c)
+ Point a1 = {map(0, 0, 3, logoL, logoR), logoB};
+ Point a2 = {map(1, 0, 3, logoL, logoR), logoT};
+ Point b1 = {map(1, 0, 3, logoL, logoR), logoB};
+ Point b2 = {map(2, 0, 3, logoL, logoR), logoT};
+ Point c1 = {map(2, 0, 3, logoL, logoR), logoT};
+ Point c2 = {map(3, 0, 3, logoL, logoR), logoB};
+
+ // Find right-angle to the path
+ // Used to thicken the single pixel paths
+ Distance deltaA = {abs(a2.x - a1.x), abs(a2.y - a1.y)};
+ float angle = tanh((float)deltaA.y / deltaA.x);
+
+ // Distance {at right angle from the paths), which will give corners for our "quads"
+ // The distance is unsigned. We will vary the signedness of the x and y components to suit the path and corner
+ Distance fromPath;
+ fromPath.x = cos(radians(90) - angle) * logoTh * 0.5;
+ fromPath.y = sin(radians(90) - angle) * logoTh * 0.5;
+
+ // Make the path thick: path a becomes quad a
+ Point aq1{a1.x - fromPath.x, a1.y - fromPath.y};
+ Point aq2{a2.x - fromPath.x, a2.y - fromPath.y};
+ Point aq3{a2.x + fromPath.x, a2.y + fromPath.y};
+ Point aq4{a1.x + fromPath.x, a1.y + fromPath.y};
+ fillTriangle(aq1.x, aq1.y, aq2.x, aq2.y, aq3.x, aq3.y, BLACK);
+ fillTriangle(aq1.x, aq1.y, aq3.x, aq3.y, aq4.x, aq4.y, BLACK);
+
+ // Make the path thick: path b becomes quad b
+ Point bq1{b1.x - fromPath.x, b1.y - fromPath.y};
+ Point bq2{b2.x - fromPath.x, b2.y - fromPath.y};
+ Point bq3{b2.x + fromPath.x, b2.y + fromPath.y};
+ Point bq4{b1.x + fromPath.x, b1.y + fromPath.y};
+ fillTriangle(bq1.x, bq1.y, bq2.x, bq2.y, bq3.x, bq3.y, BLACK);
+ fillTriangle(bq1.x, bq1.y, bq3.x, bq3.y, bq4.x, bq4.y, BLACK);
+
+ // Make the path hick: path c becomes quad c
+ Point cq1{c1.x - fromPath.x, c1.y + fromPath.y};
+ Point cq2{c2.x - fromPath.x, c2.y + fromPath.y};
+ Point cq3{c2.x + fromPath.x, c2.y - fromPath.y};
+ Point cq4{c1.x + fromPath.x, c1.y - fromPath.y};
+ fillTriangle(cq1.x, cq1.y, cq2.x, cq2.y, cq3.x, cq3.y, BLACK);
+ fillTriangle(cq1.x, cq1.y, cq3.x, cq3.y, cq4.x, cq4.y, BLACK);
+
+ // Radius the intersection of quad b and quad c
+ // Don't attempt if logo is tiny
+ if (logoTh > 3) {
+ // The radius for the cap *should* be the same as logoTh, but it's not, due to accumulated rounding
+ // We get better results just rederiving it
+ int16_t capRad = sqrt(pow(fromPath.x, 2) + pow(fromPath.y, 2));
+ fillCircle(b2.x, b2.y, capRad, BLACK);
+ }
+}
+
+#endif
\ No newline at end of file
diff --git a/src/graphics/niche/InkHUD/Applet.h b/src/graphics/niche/InkHUD/Applet.h
new file mode 100644
index 000000000..30c1bdcdc
--- /dev/null
+++ b/src/graphics/niche/InkHUD/Applet.h
@@ -0,0 +1,234 @@
+#ifdef MESHTASTIC_INCLUDE_INKHUD
+
+/*
+
+ Base class for InkHUD applets
+ Must be overriden
+
+ An applet is one "program" which may show info on the display.
+
+ ===================================
+ Preliminary notes, for the curious
+ ===================================
+
+ (This info to be streamlined, and moved to a more official documentation)
+
+ User Applets vs System Applets
+ -------------------------------
+
+ There are either "User Applets", or "System Applets".
+ This concept is only for our understanding; as far at the code is concerned, both are just "Applets"
+
+ User applets are the "normal" applets.
+ User applets are applets like "AllMessageApplet", or "MapApplet".
+ User applets may be enabled / disabled by user, via the on-screen menu.
+ Incorporating new UserApplets is easy: just add them during setupNicheGraphics
+ If a UserApplet is not added during setupNicheGraphics, it will not be built.
+ The set of available UserApplets is allowed to vary from device to device.
+
+
+ Examples of system applets include "NotificationApplet" and "MenuApplet".
+ For their own reasons, system applets each require some amount of special handling.
+
+ Drawing
+ --------
+
+ *All* drawing must be performed by an Applet.
+ Applets implement the onRender() method, where all drawing takes place.
+ Applets are told how wide and tall they are, and are expected to draw to suit this size.
+ When an applet draws, it uses co-ordinates in "Applet Space": between 0 and applet width/height.
+
+ Event-driven rendering
+ -----------------------
+
+ Applets don't render unless something on the display needs to change.
+ An applet is expected to determine for itself when it has new info to display.
+ It should interact with the firmware via the MeshModule API, via Observables, etc.
+ Please don't directly add hooks throughout the existing firmware code.
+
+ When an applet decides it would like to update the display, it should call requestUpdate()
+ The WindowManager will shortly call the onRender() method for all affected applets
+
+ An Applet may be unexpectedly asked to render at any point in time.
+
+ Applets should cache their data, but not their pixel output: they should re-render when onRender runs.
+ An Applet's dimensions are not know until onRender is called, so pre-rendering of UI elements is prohibited.
+
+ Tiles
+ -----
+
+ Applets are assigned to "Tiles".
+ Assigning an applet to a tile creates a reciprocal link between the two.
+ When an applet renders, it passes pixels to its tile.
+ The tile translates these to the correct position, to be placed into the fullscreen framebuffer.
+ User applets don't get to choose their own tile; the multiplexing is handled by the WindowManager.
+ System applets might do strange things though.
+
+ Foreground and Background
+ -------------------------
+
+ The user can cycle between applets by short-pressing the user button.
+ Any applets which are currently displayed on the display are "foreground".
+ When the user button is short pressed, and an applet is hidden, it becomes "background".
+
+ Although the WindowManager will not render background applets, they should still collect data,
+ so they are ready to display when they are brought to foreground again.
+ Even if they are in background, Applets should still request updates when an event affects them,
+ as the user may have given them permission to "autoshow"; bringing themselves foreground automatically
+
+ Applets can implement the onForeground and onBackground methods to handle this change in state.
+ They can also check their state by calling isForeground() at any time.
+
+ Active and Inactive
+ -------------------
+
+ The user can select which applets are available, using the onscreen applet selection menu.
+ Applets which are enabled in this menu are "active"; otherwise they are "inactive".
+
+ An inactive applet is expected not collect data; not to consume resources.
+ Applets are activated at boot, or when enabled via the menu.
+ They are deactivated at shutdown, or when disabled via the menu.
+
+ Applets can implement the onActivation and onDeactivation methods to handle this change in state.
+
+*/
+
+#pragma once
+
+#include "configuration.h"
+
+#include
+
+#include "./AppletFont.h"
+#include "./Applets/System/Notification/Notification.h"
+#include "./Tile.h"
+#include "./Types.h"
+#include "./WindowManager.h"
+#include "graphics/niche/Drivers/EInk/EInk.h"
+
+namespace NicheGraphics::InkHUD
+{
+
+using NicheGraphics::Drivers::EInk;
+using std::to_string;
+
+class Tile;
+class WindowManager;
+
+class Applet : public GFX
+{
+ public:
+ Applet();
+
+ void setTile(Tile *t); // Applets draw via a tile (for multiplexing)
+ Tile *getTile();
+
+ void render();
+ bool wantsToRender(); // Check whether applet wants to render
+ bool wantsToAutoshow(); // Check whether applets wants to become foreground, to show new data, if permitted
+ Drivers::EInk::UpdateTypes wantsUpdateType(); // Check which display update type the applet would prefer
+ void updateDimensions(); // Get current size from tile
+ void resetDrawingSpace(); // Makes sure every render starts with same parameters
+
+ // Change the applet's state
+
+ void activate();
+ void deactivate();
+ void bringToForeground();
+ void sendToBackground();
+
+ // Info about applet's state
+
+ bool isActive();
+ bool isForeground();
+
+ // Allow derived applets to handle changes in state
+
+ virtual void onRender() = 0; // All drawing happens here
+ virtual void onActivate() {}
+ virtual void onDeactivate() {}
+ virtual void onForeground() {}
+ virtual void onBackground() {}
+ virtual void onShutdown() {}
+ virtual void onButtonShortPress() {} // For use by System Applets only
+ virtual void onButtonLongPress() {} // For use by System Applets only
+ virtual void onLockAvailable() {} // For use by System Applets only
+
+ virtual bool approveNotification(Notification &n); // Allow an applet to veto a notification
+
+ static void setDefaultFonts(AppletFont large, AppletFont small); // Set the general purpose fonts
+ static uint16_t getHeaderHeight(); // How tall is the "standard" applet header
+
+ const char *name = nullptr; // Shown in applet selection menu
+
+ protected:
+ // Place a single pixel. All drawing methods output through here
+ void drawPixel(int16_t x, int16_t y, uint16_t color) override;
+
+ // Tell WindowManager to update display
+ void requestUpdate(EInk::UpdateTypes type = EInk::UpdateTypes::UNSPECIFIED);
+
+ // Ask for applet to be moved to foreground
+ void requestAutoshow();
+
+ uint16_t X(float f); // Map applet width, mapped from 0 to 1.0
+ uint16_t Y(float f); // Map applet height, mapped from 0 to 1.0
+ void setCrop(int16_t left, int16_t top, uint16_t width, uint16_t height); // Ignore pixels drawn outside a certain region
+ void resetCrop(); // Removes setCrop()
+
+ void setFont(AppletFont f);
+ AppletFont getFont();
+
+ uint16_t getTextWidth(std::string text);
+ uint16_t getTextWidth(const char *text);
+
+ void printAt(int16_t x, int16_t y, const char *text, HorizontalAlignment ha = LEFT, VerticalAlignment va = TOP);
+ void printAt(int16_t x, int16_t y, std::string text, HorizontalAlignment ha = LEFT, VerticalAlignment va = TOP);
+ void printThick(int16_t xCenter, int16_t yCenter, std::string text, uint8_t thicknessX, uint8_t thicknessY);
+
+ // Print text, with per-word line wrapping
+ void printWrapped(int16_t left, int16_t top, uint16_t width, std::string text);
+ uint32_t getWrappedTextHeight(int16_t left, uint16_t width, std::string text);
+
+ void hatchRegion(int16_t x, int16_t y, uint16_t w, uint16_t h, uint8_t spacing, Color color); // Fill with sparse lines
+ void drawHeader(std::string text); // Draw the standard applet header
+
+ static constexpr float LOGO_ASPECT_RATIO = 1.9; // Width:Height for drawing the Meshtastic logo
+ uint16_t getLogoWidth(uint16_t limitWidth, uint16_t limitHeight); // Size Meshtastic logo to fit within region
+ uint16_t getLogoHeight(uint16_t limitWidth, uint16_t limitHeight); // Size Meshtastic logo to fit within region
+ void drawLogo(int16_t centerX, int16_t centerY, uint16_t width, uint16_t height); // Draw the meshtastic logo
+
+ std::string hexifyNodeNum(NodeNum num);
+ SignalStrength getSignalStrength(float snr, float rssi); // Interpret SNR and RSSI, as an easy to understand value
+ std::string getTimeString(uint32_t epochSeconds); // Human readable
+ std::string getTimeString(); // Current time, human readable
+ uint16_t getActiveNodeCount(); // Duration determined by user, in onscreen menu
+ std::string localizeDistance(uint32_t meters); // Human readable distance, imperial or metric
+
+ static AppletFont fontSmall, fontLarge; // General purpose fonts, used cross-applet
+
+ private:
+ Tile *assignedTile = nullptr; // Rendered pixels are fed into a Tile object, which translates them, then passes to WM
+ bool active = false; // Has the user enabled this applet (at run-time)?
+ bool foreground = false; // Is the applet currently drawn on a tile?
+
+ bool wantRender = false; // In some situations, checked by WindowManager when updating, to skip unneeded redrawing.
+ bool wantAutoshow = false; // Does the applet have new data it would like to display in foreground?
+ NicheGraphics::Drivers::EInk::UpdateTypes wantUpdateType =
+ NicheGraphics::Drivers::EInk::UpdateTypes::UNSPECIFIED; // Which update method we'd prefer when redrawing the display
+
+ using GFX::setFont; // Make sure derived classes use AppletFont instead of AdafruitGFX fonts directly
+ using GFX::setRotation; // Block setRotation calls. Rotation is handled globally by WindowManager.
+
+ AppletFont currentFont; // As passed to setFont
+
+ // As set by setCrop
+ int16_t cropLeft;
+ int16_t cropTop;
+ uint16_t cropWidth;
+ uint16_t cropHeight;
+};
+
+}; // namespace NicheGraphics::InkHUD
+
+#endif
\ No newline at end of file
diff --git a/src/graphics/niche/InkHUD/AppletFont.cpp b/src/graphics/niche/InkHUD/AppletFont.cpp
new file mode 100644
index 000000000..bee9d33e6
--- /dev/null
+++ b/src/graphics/niche/InkHUD/AppletFont.cpp
@@ -0,0 +1,208 @@
+#ifdef MESHTASTIC_INCLUDE_INKHUD
+
+#include "./AppletFont.h"
+
+using namespace NicheGraphics;
+
+InkHUD::AppletFont::AppletFont()
+{
+ // Default constructor uses the in-built AdafruitGFX font
+}
+
+InkHUD::AppletFont::AppletFont(const GFXfont &adafruitGFXFont) : gfxFont(&adafruitGFXFont)
+{
+ // AdafruitGFX fonts are drawn relative to a "cursor line";
+ // they print as if the glyphs resting on the line of piece of ruled paper.
+ // The glyphs also each have a different height.
+
+ // To simplify drawing, we will scan the entire font now, and determine an appropriate height for a line of text
+ // We also need to know where that "cursor line" sits inside this "line height";
+ // we need this additional info in order to align text by top-left, bottom-right, etc
+
+ // AdafruitGFX fonts do declare a line-height, but this seems to include a certain amount of padding,
+ // which we'd rather not deal with. If we want padding, we'll add it manually.
+
+ // Scan each glyph in the AdafruitGFX font
+ for (uint16_t i = 0; i <= (gfxFont->last - gfxFont->first); i++) {
+ uint8_t glyphHeight = gfxFont->glyph[i].height; // Height of glyph
+ this->height = max(this->height, glyphHeight); // Store if it's a new max
+
+ // Calculate how far the glyph rises the cursor line
+ // Store if new max value
+ // Caution: signed and unsigned types
+ int8_t glyphAscender = 0 - gfxFont->glyph[i].yOffset;
+ if (glyphAscender > 0)
+ this->ascenderHeight = max(this->ascenderHeight, (uint8_t)glyphAscender);
+ }
+
+ // Determine how far characters may hang "below the line"
+ descenderHeight = height - ascenderHeight;
+
+ // Find how far the cursor advances when we "print" a space character
+ spaceCharWidth = gfxFont->glyph[(uint8_t)' ' - gfxFont->first].xAdvance;
+}
+
+uint8_t InkHUD::AppletFont::lineHeight()
+{
+ return this->height;
+}
+
+// AdafruitGFX fonts print characters so that they nicely on an imaginary line (think: ruled paper).
+// This value is the height of the font, above that imaginary line.
+// Used to calculate the true height of the font
+uint8_t InkHUD::AppletFont::heightAboveCursor()
+{
+ return this->ascenderHeight;
+}
+
+// AdafruitGFX fonts print characters so that they nicely on an imaginary line (think: ruled paper).
+// This value is the height of the font, below that imaginary line.
+// Used to calculate the true height of the font
+uint8_t InkHUD::AppletFont::heightBelowCursor()
+{
+ return this->descenderHeight;
+}
+
+// Width of the space character
+// Used with Applet::printWrapped
+uint8_t InkHUD::AppletFont::widthBetweenWords()
+{
+ return this->spaceCharWidth;
+}
+
+// Add to the list of substituted glyphs
+// This "find and replace" operation will be run before text is printed
+// Used to swap out UTF8 special characters, either with a custom font, or with a suitable ASCII approximation
+void InkHUD::AppletFont::addSubstitution(const char *from, const char *to)
+{
+ substitutions.push_back({.from = from, .to = to});
+}
+
+// Run all registered subtitutions on a string
+// Used to swap out UTF8 special chars
+void InkHUD::AppletFont::applySubstitutions(std::string *text)
+{
+ // For each substitution
+ for (Substitution s : substitutions) {
+
+ // Find and replace
+ // - search for Substitution::from
+ // - replace with Subsitution::to
+ size_t i = text->find(s.from);
+ while (i != std::string::npos) {
+ text->replace(i, strlen(s.from), s.to);
+ i = text->find(s.from, i); // Continue looking from last position
+ }
+ }
+}
+
+// Apply a set of substitutions which remap UTF8 for a Windows-1251 font
+// Windows-1251 is an 8-bit character encoding, designed to cover languages that use the Cyrillic script
+void InkHUD::AppletFont::addSubstitutionsWin1251()
+{
+ addSubstitution("Ђ", "\x80");
+ addSubstitution("Ѓ", "\x81");
+ addSubstitution("ѓ", "\x83");
+ addSubstitution("€", "\x88");
+ addSubstitution("Љ", "\x8A");
+ addSubstitution("Њ", "\x8C");
+ addSubstitution("Ќ", "\x8D");
+ addSubstitution("Ћ", "\x8E");
+ addSubstitution("Џ", "\x8F");
+
+ addSubstitution("ђ", "\x90");
+ addSubstitution("љ", "\x9A");
+ addSubstitution("њ", "\x9C");
+ addSubstitution("ќ", "\x9D");
+ addSubstitution("ћ", "\x9E");
+ addSubstitution("џ", "\x9F");
+
+ addSubstitution("Ў", "\xA1");
+ addSubstitution("ў", "\xA2");
+ addSubstitution("Ј", "\xA3");
+ addSubstitution("Ґ", "\xA5");
+ addSubstitution("Ё", "\xA8");
+ addSubstitution("Є", "\xAA");
+ addSubstitution("Ї", "\xAF");
+
+ addSubstitution("І", "\xB2");
+ addSubstitution("і", "\xB3");
+ addSubstitution("ґ", "\xB4");
+ addSubstitution("ё", "\xB8");
+ addSubstitution("№", "\xB9");
+ addSubstitution("є", "\xBA");
+ addSubstitution("ј", "\xBC");
+ addSubstitution("Ѕ", "\xBD");
+ addSubstitution("ѕ", "\xBE");
+ addSubstitution("ї", "\xBF");
+
+ addSubstitution("А", "\xC0");
+ addSubstitution("Б", "\xC1");
+ addSubstitution("В", "\xC2");
+ addSubstitution("Г", "\xC3");
+ addSubstitution("Д", "\xC4");
+ addSubstitution("Е", "\xC5");
+ addSubstitution("Ж", "\xC6");
+ addSubstitution("З", "\xC7");
+ addSubstitution("И", "\xC8");
+ addSubstitution("Й", "\xC9");
+ addSubstitution("К", "\xCA");
+ addSubstitution("Л", "\xCB");
+ addSubstitution("М", "\xCC");
+ addSubstitution("Н", "\xCD");
+ addSubstitution("О", "\xCE");
+ addSubstitution("П", "\xCF");
+
+ addSubstitution("Р", "\xD0");
+ addSubstitution("С", "\xD1");
+ addSubstitution("Т", "\xD2");
+ addSubstitution("У", "\xD3");
+ addSubstitution("Ф", "\xD4");
+ addSubstitution("Х", "\xD5");
+ addSubstitution("Ц", "\xD6");
+ addSubstitution("Ч", "\xD7");
+ addSubstitution("Ш", "\xD8");
+ addSubstitution("Щ", "\xD9");
+ addSubstitution("Ъ", "\xDA");
+ addSubstitution("Ы", "\xDB");
+ addSubstitution("Ь", "\xDC");
+ addSubstitution("Э", "\xDD");
+ addSubstitution("Ю", "\xDE");
+ addSubstitution("Я", "\xDF");
+
+ addSubstitution("а", "\xE0");
+ addSubstitution("б", "\xE1");
+ addSubstitution("в", "\xE2");
+ addSubstitution("г", "\xE3");
+ addSubstitution("д", "\xE4");
+ addSubstitution("е", "\xE5");
+ addSubstitution("ж", "\xE6");
+ addSubstitution("з", "\xE7");
+ addSubstitution("и", "\xE8");
+ addSubstitution("й", "\xE9");
+ addSubstitution("к", "\xEA");
+ addSubstitution("л", "\xEB");
+ addSubstitution("м", "\xEC");
+ addSubstitution("н", "\xED");
+ addSubstitution("о", "\xEE");
+ addSubstitution("п", "\xEF");
+
+ addSubstitution("р", "\xF0");
+ addSubstitution("с", "\xF1");
+ addSubstitution("т", "\xF2");
+ addSubstitution("у", "\xF3");
+ addSubstitution("ф", "\xF4");
+ addSubstitution("х", "\xF5");
+ addSubstitution("ц", "\xF6");
+ addSubstitution("ч", "\xF7");
+ addSubstitution("ш", "\xF8");
+ addSubstitution("щ", "\xF9");
+ addSubstitution("ъ", "\xFA");
+ addSubstitution("ы", "\xFB");
+ addSubstitution("ь", "\xFC");
+ addSubstitution("э", "\xFD");
+ addSubstitution("ю", "\xFE");
+ addSubstitution("я", "\xFF");
+}
+
+#endif
\ No newline at end of file
diff --git a/src/graphics/niche/InkHUD/AppletFont.h b/src/graphics/niche/InkHUD/AppletFont.h
new file mode 100644
index 000000000..89f901c94
--- /dev/null
+++ b/src/graphics/niche/InkHUD/AppletFont.h
@@ -0,0 +1,59 @@
+#ifdef MESHTASTIC_INCLUDE_INKHUD
+
+/*
+
+ Wrapper class for an AdafruitGFX font
+ Pre-calculates some font dimension info which InkHUD uses repeatedly
+
+ Also contains an optional set of "substitutions".
+ These can be used to detect special UTF8 chars, and replace occurrences with a remapped char val to suit a custom font
+ These can also be used to swap UTF8 chars for a suitable ASCII substitution (e.g. German ö -> oe, etc)
+
+*/
+
+#pragma once
+
+#include "configuration.h"
+
+#include
+
+namespace NicheGraphics::InkHUD
+{
+
+// An AdafruitGFX font, bundled with precalculated dimensions which are used frequently by InkHUD
+class AppletFont
+{
+ public:
+ AppletFont();
+ AppletFont(const GFXfont &adafruitGFXFont);
+ uint8_t lineHeight();
+ uint8_t heightAboveCursor();
+ uint8_t heightBelowCursor();
+ uint8_t widthBetweenWords();
+
+ void applySubstitutions(std::string *text); // Run all char-substitution operations, prior to printing
+ void addSubstitution(const char *from, const char *to); // Register a find-replace action, for remapping UTF8 chars
+ void addSubstitutionsWin1251(); // Cyrillic fonts: remap UTF8 values to their Win-1251 equivalent
+ // Todo: Polish font
+
+ const GFXfont *gfxFont = NULL; // Default value: in-built AdafruitGFX font
+
+ private:
+ uint8_t height = 8; // Default value: in-built AdafruitGFX font
+ uint8_t ascenderHeight = 0; // Default value: in-built AdafruitGFX font
+ uint8_t descenderHeight = 8; // Default value: in-built AdafruitGFX font
+ uint8_t spaceCharWidth = 8; // Default value: in-built AdafruitGFX font
+
+ // One pair of find-replace values, for substituting or remapping UTF8 chars
+ struct Substitution {
+ const char *from;
+ const char *to;
+ };
+
+ // List of all character substitutions to run, prior to printing a string
+ std::vector substitutions;
+};
+
+} // namespace NicheGraphics::InkHUD
+
+#endif
\ No newline at end of file
diff --git a/src/graphics/niche/InkHUD/Applets/Bases/Map/MapApplet.cpp b/src/graphics/niche/InkHUD/Applets/Bases/Map/MapApplet.cpp
new file mode 100644
index 000000000..21f404349
--- /dev/null
+++ b/src/graphics/niche/InkHUD/Applets/Bases/Map/MapApplet.cpp
@@ -0,0 +1,429 @@
+#ifdef MESHTASTIC_INCLUDE_INKHUD
+
+#include "./MapApplet.h"
+
+using namespace NicheGraphics;
+
+void InkHUD::MapApplet::onRender()
+{
+ setFont(fontSmall);
+
+ // Abort if no markers to render
+ if (!enoughMarkers()) {
+ printAt(X(0.5), Y(0.5) - (getFont().lineHeight() / 2), "Node positions", CENTER, MIDDLE);
+ printAt(X(0.5), Y(0.5) + (getFont().lineHeight() / 2), "will appear here", CENTER, MIDDLE);
+ return;
+ }
+
+ // Find center of map
+ // - latitude and longitude
+ // - will be placed at X(0.5), Y(0.5)
+ getMapCenter(&latCenter, &lngCenter);
+
+ // Calculate North+East distance of each node to map center
+ // - which nodes to use controlled by virtual shouldDrawNode method
+ calculateAllMarkers();
+
+ // Set the region shown on the map
+ // - default: fit all nodes, plus padding
+ // - maybe overriden by derived applet
+ getMapSize(&widthMeters, &heightMeters);
+
+ // Set the metersToPx conversion value
+ calculateMapScale();
+
+ // Special marker for own node
+ meshtastic_NodeInfoLite *ourNode = nodeDB->getMeshNode(nodeDB->getNodeNum());
+ if (ourNode && nodeDB->hasValidPosition(ourNode))
+ drawLabeledMarker(ourNode);
+
+ // Draw all markers
+ for (Marker m : markers) {
+ int16_t x = X(0.5) + (m.eastMeters * metersToPx);
+ int16_t y = Y(0.5) - (m.northMeters * metersToPx);
+
+ // Cross Size
+ constexpr uint16_t csMin = 5;
+ constexpr uint16_t csMax = 12;
+
+ // Too many hops away
+ if (m.hasHopsAway && m.hopsAway > config.lora.hop_limit) // Too many mops
+ printAt(x, y, "!", CENTER, MIDDLE);
+ else if (!m.hasHopsAway) // Unknown hops
+ drawCross(x, y, csMin);
+ else // The fewer hops, the larger the cross
+ drawCross(x, y, map(m.hopsAway, 0, config.lora.hop_limit, csMax, csMin));
+ }
+}
+
+// Find the center point, in the middle of all node positions
+// Calculated values are written to the *lat and *long pointer args
+// - Finds the "mean lat long"
+// - Calculates furthest nodes from "mean lat long"
+// - Place map center directly between these furthest nodes
+
+void InkHUD::MapApplet::getMapCenter(float *lat, float *lng)
+{
+ // Find mean lat long coords
+ // ============================
+ // - assigning X, Y and Z values to position on Earth's surface in 3D space, relative to center of planet
+ // - averages the x, y and z coords
+ // - uses tan to find angles for lat / long degrees
+ // - longitude: triangle formed by x and y (on plane of the equator)
+ // - latitude: triangle formed by z (north south),
+ // and the line along plane of equator which stetches from earth's axis to where point xyz intersects planet's surface
+
+ // Working totals, averaged after nodeDB processed
+ uint32_t positionCount = 0;
+ float xAvg = 0;
+ float yAvg = 0;
+ float zAvg = 0;
+
+ // For each node in db
+ for (uint32_t i = 0; i < nodeDB->getNumMeshNodes(); i++) {
+ meshtastic_NodeInfoLite *node = nodeDB->getMeshNodeByIndex(i);
+
+ // Skip if no position
+ if (!nodeDB->hasValidPosition(node))
+ continue;
+
+ // Skip if derived applet doesn't want to show this node on the map
+ if (!shouldDrawNode(node))
+ continue;
+
+ // Latitude and Longitude of node, in radians
+ float latRad = node->position.latitude_i * (1e-7) * DEG_TO_RAD;
+ float lngRad = node->position.longitude_i * (1e-7) * DEG_TO_RAD;
+
+ // Convert to cartesian points, with center of earth at 0, 0, 0
+ // Exact distance from center is irrelevant, as we're only interested in the vector
+ float x = cos(latRad) * cos(lngRad);
+ float y = cos(latRad) * sin(lngRad);
+ float z = sin(latRad);
+
+ // To find mean values shortly
+ xAvg += x;
+ yAvg += y;
+ zAvg += z;
+ positionCount++;
+ }
+
+ // All NodeDB processed, find mean values
+ xAvg /= positionCount;
+ yAvg /= positionCount;
+ zAvg /= positionCount;
+
+ // Longitude from cartesian coords
+ // (Angle from 3D coords describing a point of globe's surface)
+ /*
+ UK
+ /-------\
+ (Top View) /- -\
+ /- (You) -\
+ /- . -\
+ /- . X -\
+ Asia - ... - USA
+ \- Y -/
+ \- -/
+ \- -/
+ \- -/
+ \- -----/
+ Pacific
+
+ */
+
+ *lng = atan2(yAvg, xAvg) * RAD_TO_DEG;
+
+ // Latitude from cartesian cooods
+ // (Angle from 3D coords describing a point on the globe's surface)
+ // As latitude increases, distance from the Earth's north-south axis out to our surface point decreases.
+ // Means we need to first find the hypotenuse which becomes base of our triangle in the second step
+ /*
+ UK North
+ /-------\ (Front View) /-------\
+ (Top View) /- -\ /- -\
+ /- (You) -\ /-(You) -\
+ /- /. -\ /- . -\
+ /- √X²+Y²/ . X -\ /- Z . -\
+ Asia - /... - USA - ..... -
+ \- Y -/ \- √X²+Y² -/
+ \- -/ \- -/
+ \- -/ \- -/
+ \- -/ \- -/
+ \- -----/ \- -----/
+ Pacific South
+ */
+
+ float hypotenuse = sqrt((xAvg * xAvg) + (yAvg * yAvg)); // Distance from globe's north-south axis to surface intersect
+ *lat = atan2(zAvg, hypotenuse) * RAD_TO_DEG;
+
+ // ----------------------------------------------
+ // This has given us the "mean position"
+ // This will be a position *somewhere* near the center of our nodes.
+ // What we actually want is to place our center so that our outermost nodes end up on the border of our map.
+ // The only real use of our "mean position" is to give us a reference frame:
+ // which direction is east, and which is west.
+ //------------------------------------------------
+
+ // Find furthest nodes from "mean lat long"
+ // ========================================
+
+ float northernmost = latCenter;
+ float southernmost = latCenter;
+ float easternmost = lngCenter;
+ float westernmost = lngCenter;
+
+ for (uint8_t i = 0; i < nodeDB->getNumMeshNodes(); i++) {
+ meshtastic_NodeInfoLite *node = nodeDB->getMeshNodeByIndex(i);
+
+ // Skip if no position
+ if (!nodeDB->hasValidPosition(node))
+ continue;
+
+ // Skip if derived applet doesn't want to show this node on the map
+ if (!shouldDrawNode(node))
+ continue;
+
+ // Check for a new top or bottom latitude
+ float lat = node->position.latitude_i * 1e-7;
+ northernmost = max(northernmost, lat);
+ southernmost = min(southernmost, lat);
+
+ // Longitude is trickier
+ float lng = node->position.longitude_i * 1e-7;
+ float degEastward = fmod(((lng - lngCenter) + 360), 360); // Degrees travelled east from lngCenter to reach node
+ float degWestward = abs(fmod(((lng - lngCenter) - 360), 360)); // Degrees travelled west from lngCenter to reach node
+ if (degEastward < degWestward)
+ easternmost = max(easternmost, lngCenter + degEastward);
+ else
+ westernmost = min(westernmost, lngCenter - degWestward);
+ }
+
+ // Todo: check for issues with map spans >180 deg. MQTT only..
+ latCenter = (northernmost + southernmost) / 2;
+ lngCenter = (westernmost + easternmost) / 2;
+
+ // In case our new center is west of -180, or east of +180, for some reason
+ lngCenter = fmod(lngCenter, 180);
+}
+
+// Size of map in meters
+// Grown to fit the nodes furthest from map center
+// Overridable if derived applet wants a custom map size (fixed size?)
+void InkHUD::MapApplet::getMapSize(uint32_t *widthMeters, uint32_t *heightMeters)
+{
+ // Reset the value
+ *widthMeters = 0;
+ *heightMeters = 0;
+
+ // Find the greatest distance horizontally and vertically from map center
+ for (Marker m : markers) {
+ *widthMeters = max(*widthMeters, (uint32_t)abs(m.eastMeters) * 2);
+ *heightMeters = max(*heightMeters, (uint32_t)abs(m.northMeters) * 2);
+ }
+
+ // Add padding
+ *widthMeters *= 1.1;
+ *heightMeters *= 1.1;
+}
+
+// Convert and store info we need for drawing a marker
+// Lat / long to "meters relative to map center", for position on screen
+// Info about hopsAway, for marker size
+InkHUD::MapApplet::Marker InkHUD::MapApplet::calculateMarker(float lat, float lng, bool hasHopsAway, uint8_t hopsAway)
+{
+ assert(lat != 0 || lng != 0); // Not null island. Applets should check this before calling.
+
+ // Bearing and distance from map center to node
+ float distanceFromCenter = GeoCoord::latLongToMeter(latCenter, lngCenter, lat, lng);
+ float bearingFromCenter = GeoCoord::bearing(latCenter, lngCenter, lat, lng); // in radians
+
+ // Split into meters north and meters east components (signed)
+ // - signedness of cos / sin automatically sets negative if south or west
+ float northMeters = cos(bearingFromCenter) * distanceFromCenter;
+ float eastMeters = sin(bearingFromCenter) * distanceFromCenter;
+
+ // Store this as a new marker
+ Marker m;
+ m.eastMeters = eastMeters;
+ m.northMeters = northMeters;
+ m.hasHopsAway = hasHopsAway;
+ m.hopsAway = hopsAway;
+ return m;
+}
+
+// Draw a marker on the map for a node, with a shortname label, and backing box
+void InkHUD::MapApplet::drawLabeledMarker(meshtastic_NodeInfoLite *node)
+{
+ // Find x and y position based on node's position in nodeDB
+ assert(nodeDB->hasValidPosition(node));
+ Marker m = calculateMarker(node->position.latitude_i * 1e-7, // Lat, converted from Meshtastic's internal int32 style
+ node->position.longitude_i * 1e-7, // Long, convered from Meshtastic's internal int32 style
+ node->has_hops_away, // Is the hopsAway number valid
+ node->hops_away // Hops away
+ );
+
+ // Convert to pixel coords
+ int16_t markerX = X(0.5) + (m.eastMeters * metersToPx);
+ int16_t markerY = Y(0.5) - (m.northMeters * metersToPx);
+
+ constexpr uint16_t paddingH = 2;
+ constexpr uint16_t paddingW = 4;
+ uint16_t paddingInnerW = 2; // Zero'd out if no text
+ constexpr uint16_t markerSizeMax = 12; // Size of cross (if marker uses a cross)
+ constexpr uint16_t markerSizeMin = 5;
+
+ int16_t textX;
+ int16_t textY;
+ uint16_t textW;
+ uint16_t textH;
+ int16_t labelX;
+ int16_t labelY;
+ uint16_t labelW;
+ uint16_t labelH;
+ uint8_t markerSize;
+
+ bool tooManyHops = node->hops_away > config.lora.hop_limit;
+ bool isOurNode = node->num == nodeDB->getNodeNum();
+ bool unknownHops = !node->has_hops_away && !isOurNode;
+
+ // We will draw a left or right hand variant, to place text towards screen center
+ // Hopfully avoid text spilling off screen
+ // Most values are the same, regardless of left-right handedness
+
+ // Pick emblem style
+ if (tooManyHops)
+ markerSize = getTextWidth("!");
+ else if (unknownHops)
+ markerSize = markerSizeMin;
+ else
+ markerSize = map(node->hops_away, 0, config.lora.hop_limit, markerSizeMax, markerSizeMin);
+
+ // Common dimensions (left or right variant)
+ textW = getTextWidth(node->user.short_name);
+ if (textW == 0)
+ paddingInnerW = 0; // If no text, no padding for text
+ textH = fontSmall.lineHeight();
+ labelH = paddingH + max((int16_t)(textH), (int16_t)markerSize) + paddingH;
+ labelY = markerY - (labelH / 2);
+ textY = markerY;
+ labelW = paddingW + markerSize + paddingInnerW + textW + paddingW; // Width is same whether right or left hand variant
+
+ // Left-side variant
+ if (markerX < width() / 2) {
+ labelX = markerX - (markerSize / 2) - paddingW;
+ textX = labelX + paddingW + markerSize + paddingInnerW;
+ }
+
+ // Right-side variant
+ else {
+ labelX = markerX - (markerSize / 2) - paddingInnerW - textW - paddingW;
+ textX = labelX + paddingW;
+ }
+
+ // Backing box
+ fillRect(labelX, labelY, labelW, labelH, WHITE);
+ drawRect(labelX, labelY, labelW, labelH, BLACK);
+
+ // Short name
+ printAt(textX, textY, node->user.short_name, LEFT, MIDDLE);
+
+ // If the label is for our own node,
+ // fade it by overdrawing partially with white
+ if (node == nodeDB->getMeshNode(nodeDB->getNodeNum()))
+ hatchRegion(labelX, labelY, labelW, labelH, 2, WHITE);
+
+ // Draw the marker emblem
+ // - after the fading, because hatching (own node) can align with cross and make it look weird
+ if (tooManyHops)
+ printAt(markerX, markerY, "!", CENTER, MIDDLE);
+ else
+ drawCross(markerX, markerY, markerSize); // The fewer the hops, the larger the marker. Also handles unknownHops
+}
+
+// Check if we actually have enough nodes which would be shown on the map
+// Need at least two, to draw a sensible map
+bool InkHUD::MapApplet::enoughMarkers()
+{
+ uint8_t count = 0;
+ for (uint8_t i = 0; i < nodeDB->getNumMeshNodes(); i++) {
+ meshtastic_NodeInfoLite *node = nodeDB->getMeshNodeByIndex(i);
+
+ // Count nodes
+ if (nodeDB->hasValidPosition(node) && shouldDrawNode(node))
+ count++;
+
+ // We need to find two
+ if (count == 2)
+ return true; // Two nodes is enough for a sensible map
+ }
+
+ return false; // No nodes would be drawn (or just the one, uselessly at 0,0)
+}
+
+// Calculate how far north and east of map center each node is
+// Derived applets can control which nodes to calculate (and later, draw) by overriding MapApplet::shouldDrawNode
+void InkHUD::MapApplet::calculateAllMarkers()
+{
+ // Clear old markers
+ markers.clear();
+
+ // For each node in db
+ for (uint32_t i = 0; i < nodeDB->getNumMeshNodes(); i++) {
+ meshtastic_NodeInfoLite *node = nodeDB->getMeshNodeByIndex(i);
+
+ // Skip if no position
+ if (!nodeDB->hasValidPosition(node))
+ continue;
+
+ // Skip if derived applet doesn't want to show this node on the map
+ if (!shouldDrawNode(node))
+ continue;
+
+ // Skip if our own node
+ // - special handling in render()
+ if (node->num == nodeDB->getNodeNum())
+ continue;
+
+ // Calculate marker and store it
+ markers.push_back(
+ calculateMarker(node->position.latitude_i * 1e-7, // Lat, converted from Meshtastic's internal int32 style
+ node->position.longitude_i * 1e-7, // Long, convered from Meshtastic's internal int32 style
+ node->has_hops_away, // Is the hopsAway number valid
+ node->hops_away // Hops away
+ ));
+ }
+}
+
+// Determine the conversion factor between metres, and pixels on screen
+// May be overriden by derived applet, if custom scale required (fixed map size?)
+void InkHUD::MapApplet::calculateMapScale()
+{
+ // Aspect ratio of map and screen
+ // - larger = wide, smaller = tall
+ // - used to set scale, so that widest map dimension fits in applet
+ float mapAspectRatio = (float)widthMeters / heightMeters;
+ float appletAspectRatio = (float)width() / height();
+
+ // "Shrink to fit"
+ // Scale the map so that the largest dimension is fully displayed
+ // Because aspect ratio will be maintained, the other dimension will appear "padded"
+ if (mapAspectRatio > appletAspectRatio)
+ metersToPx = (float)width() / widthMeters; // Too wide for applet. Constrain to fit width.
+ else
+ metersToPx = (float)height() / heightMeters; // Too tall for applet. Constrain to fit height.
+}
+
+// Draw an x, centered on a specific point
+// Most markers will draw with this method
+void InkHUD::MapApplet::drawCross(int16_t x, int16_t y, uint8_t size)
+{
+ int16_t x0 = x - (size / 2);
+ int16_t y0 = y - (size / 2);
+ int16_t x1 = x0 + size - 1;
+ int16_t y1 = y0 + size - 1;
+ drawLine(x0, y0, x1, y1, BLACK);
+ drawLine(x0, y1, x1, y0, BLACK);
+}
+
+#endif
\ No newline at end of file
diff --git a/src/graphics/niche/InkHUD/Applets/Bases/Map/MapApplet.h b/src/graphics/niche/InkHUD/Applets/Bases/Map/MapApplet.h
new file mode 100644
index 000000000..fd5245631
--- /dev/null
+++ b/src/graphics/niche/InkHUD/Applets/Bases/Map/MapApplet.h
@@ -0,0 +1,66 @@
+#ifdef MESHTASTIC_INCLUDE_INKHUD
+
+/*
+
+Base class for Applets which show nodes on a map
+
+Plots position of for a selection of nodes, with north facing up.
+Size of cross represents hops away.
+Our own node is identified with a faded label.
+
+The base applet doesn't handle any events; this is left to the derived applets.
+
+*/
+
+#pragma once
+
+#include "configuration.h"
+
+#include "graphics/niche/InkHUD/Applet.h"
+
+#include "MeshModule.h"
+#include "gps/GeoCoord.h"
+
+namespace NicheGraphics::InkHUD
+{
+
+class MapApplet : public Applet
+{
+ public:
+ void onRender() override;
+
+ protected:
+ virtual bool shouldDrawNode(meshtastic_NodeInfoLite *node) { return true; } // Allow derived applets to filter the nodes
+ virtual void getMapCenter(float *lat, float *lng);
+ virtual void getMapSize(uint32_t *widthMeters, uint32_t *heightMeters);
+
+ bool enoughMarkers(); // Anything to draw?
+ void drawLabeledMarker(meshtastic_NodeInfoLite *node); // Highlight a specific marker
+
+ private:
+ // Position of markers to be drawn, relative to map center
+ // HopsAway info used to determine marker size
+ struct Marker {
+ float eastMeters = 0; // Meters east of mapCenter. Negative if west.
+ float northMeters = 0; // Meters north of mapCenter. Negative if south.
+ bool hasHopsAway = false;
+ uint8_t hopsAway = 0;
+ };
+
+ Marker calculateMarker(float lat, float lng, bool hasHopsAway, uint8_t hopsAway);
+ void calculateAllMarkers();
+ void calculateMapScale(); // Conversion factor for meters to pixels
+ void drawCross(int16_t x, int16_t y, uint8_t size); // Draw the X used for most markers
+
+ float metersToPx = 0; // Conversion factor for meters to pixels
+ float latCenter = 0; // Map center: latitude
+ float lngCenter = 0; // Map center: longitude
+
+ std::list markers;
+ uint32_t widthMeters = 0; // Map width: meters
+ uint32_t heightMeters = 0; // Map height: meters
+};
+
+} // namespace NicheGraphics::InkHUD
+
+#endif
\ No newline at end of file
diff --git a/src/graphics/niche/InkHUD/Applets/Bases/NodeList/NodeListApplet.cpp b/src/graphics/niche/InkHUD/Applets/Bases/NodeList/NodeListApplet.cpp
new file mode 100644
index 000000000..5d60e6800
--- /dev/null
+++ b/src/graphics/niche/InkHUD/Applets/Bases/NodeList/NodeListApplet.cpp
@@ -0,0 +1,283 @@
+#ifdef MESHTASTIC_INCLUDE_INKHUD
+
+#include "RTC.h"
+
+#include "GeoCoord.h"
+#include "NodeDB.h"
+
+#include "./NodeListApplet.h"
+
+using namespace NicheGraphics;
+
+InkHUD::NodeListApplet::NodeListApplet(const char *name) : MeshModule(name)
+{
+ // We only need to be promiscuous in order to hear NodeInfo, apparently. See NodeInfoModule
+ // For all other packets, we manually reimplement isPromiscuous=false in wantPacket
+ MeshModule::isPromiscuous = true;
+}
+
+// Do we want to process this packet with handleReceived()?
+bool InkHUD::NodeListApplet::wantPacket(const meshtastic_MeshPacket *p)
+{
+ // Only interested if:
+ return isActive() // Applet is active
+ && !isFromUs(p) // Packet is incoming (not outgoing)
+ && (isToUs(p) || isBroadcast(p->to) || // Either: intended for us,
+ p->decoded.portnum == meshtastic_PortNum_NODEINFO_APP); // or nodeinfo
+
+ // Note: special handling of NodeInfo is to match NodeInfoModule
+ // To match the behavior seen in the client apps:
+ // - NodeInfoModule's ProtoBufModule base is "promiscuous"
+ // - All other activity is *not* promiscuous
+ // To achieve this, our MeshModule *is* promiscious, and we're manually reimplementing non-promiscuous behavior here,
+ // to match the code in MeshModule::callModules
+}
+
+// MeshModule packets arrive here
+// Extract the info and pass it to the derived applet
+// Derived applet will store the CardInfo and perform any required sorting of the CardInfo collection
+// Derived applet might also need to keep other tallies (active nodes count?)
+ProcessMessage InkHUD::NodeListApplet::handleReceived(const meshtastic_MeshPacket &mp)
+{
+ // Abort if applet fully deactivated
+ // Already handled by wantPacket in this case, but good practice for all applets, as some *do* require this early return
+ if (!isActive())
+ return ProcessMessage::CONTINUE;
+
+ // Assemble info: from this event
+ CardInfo c;
+ c.nodeNum = mp.from;
+ c.signal = getSignalStrength(mp.rx_snr, mp.rx_rssi);
+
+ // Assemble info: from nodeDB (needed to detect changes)
+ meshtastic_NodeInfoLite *node = nodeDB->getMeshNode(c.nodeNum);
+ meshtastic_NodeInfoLite *ourNode = nodeDB->getMeshNode(nodeDB->getNodeNum());
+ if (node) {
+ if (node->has_hops_away)
+ c.hopsAway = node->hops_away;
+
+ if (nodeDB->hasValidPosition(node) && nodeDB->hasValidPosition(ourNode)) {
+ // Get lat and long as float
+ // Meshtastic stores these as integers internally
+ float ourLat = ourNode->position.latitude_i * 1e-7;
+ float ourLong = ourNode->position.longitude_i * 1e-7;
+ float theirLat = node->position.latitude_i * 1e-7;
+ float theirLong = node->position.longitude_i * 1e-7;
+
+ c.distanceMeters = (int32_t)GeoCoord::latLongToMeter(theirLat, theirLong, ourLat, ourLong);
+ }
+ }
+
+ // Pass to the derived applet
+ // Derived applet is responsible for requesting update, if justified
+ // That request will eventually trigger our class' onRender method
+ handleParsed(c);
+
+ return ProcessMessage::CONTINUE; // Let others look at this message also if they want
+}
+
+// Maximum number of cards we may ever need to render, in our tallest layout config
+// May be slightly in excess of the true value: header not accounted for
+uint8_t InkHUD::NodeListApplet::maxCards()
+{
+ // Cache result. Shouldn't change during execution
+ static uint8_t cards = 0;
+
+ if (!cards) {
+ const uint16_t height = Tile::maxDisplayDimension();
+
+ // Use a loop instead of arithmetic, because it's easier for my brain to follow
+ // Add cards one by one, until the latest card (without margin) extends below screen
+
+ uint16_t y = cardH; // First card: no margin above
+ cards = 1;
+
+ while (y < height) {
+ y += cardMarginH;
+ y += cardH;
+ cards++;
+ }
+ }
+
+ return cards;
+}
+
+// Draw using info which derived applet placed into NodeListApplet::cards for us
+void InkHUD::NodeListApplet::onRender()
+{
+
+ // ================================
+ // Draw the standard applet header
+ // ================================
+
+ drawHeader(getHeaderText()); // Ask derived applet for the title
+
+ // Dimensions of the header
+ int16_t headerDivY = getHeaderHeight() - 1;
+ constexpr uint16_t padDivH = 2;
+
+ // ========================
+ // Draw the main node list
+ // ========================
+
+ // const uint8_t cardMarginH = fontSmall.lineHeight() / 2; // Gap between cards
+ // const uint16_t cardH = fontLarge.lineHeight() + fontSmall.lineHeight() + cardMarginH;
+
+ // Imaginary vertical line dividing left-side and right-side info
+ // Long-name will crop here
+ const uint16_t dividerX = (width() - 1) - getTextWidth("X Hops");
+
+ // Y value (top) of the current card. Increases as we draw.
+ uint16_t cardTopY = headerDivY + padDivH;
+
+ // -- Each node in list --
+ for (auto card = cards.begin(); card != cards.end(); ++card) {
+
+ // Gather info
+ // ========================================
+ NodeNum &nodeNum = card->nodeNum;
+ SignalStrength &signal = card->signal;
+ std::string longName; // handled below
+ std::string shortName; // handled below
+ std::string distance; // handled below;
+ uint8_t &hopsAway = card->hopsAway;
+
+ meshtastic_NodeInfoLite *node = nodeDB->getMeshNode(nodeNum);
+
+ // -- Shortname --
+ // use "?" if unknown
+ if (node && node->has_user)
+ shortName = node->user.short_name;
+ else
+ shortName = "?";
+
+ // -- Longname --
+ // use node id if unknown
+ if (node && node->has_user)
+ longName = node->user.long_name; // Found in nodeDB
+ else {
+ // Not found in nodeDB, show a hex nodeid instead
+ longName = hexifyNodeNum(nodeNum);
+ }
+
+ // -- Distance --
+ if (card->distanceMeters != CardInfo::DISTANCE_UNKNOWN)
+ distance = localizeDistance(card->distanceMeters);
+
+ // Draw the info
+ // ====================================
+
+ // Define two lines of text for the card
+ // We will center our text on these lines
+ uint16_t lineAY = cardTopY + (fontLarge.lineHeight() / 2);
+ uint16_t lineBY = cardTopY + fontLarge.lineHeight() + (fontSmall.lineHeight() / 2);
+
+ // Print the short name
+ setFont(fontLarge);
+ printAt(0, lineAY, shortName, LEFT, MIDDLE);
+
+ // Print the distance
+ setFont(fontSmall);
+ printAt(width() - 1, lineBY, distance, RIGHT, MIDDLE);
+
+ // If we have a direct connection to the node, draw the signal indicator
+ if (hopsAway == 0 && signal != SIGNAL_UNKNOWN) {
+ uint16_t signalW = getTextWidth("Xkm"); // Indicator should be similar width to distance label
+ uint16_t signalH = fontLarge.lineHeight() * 0.75;
+ int16_t signalY = lineAY + (fontLarge.lineHeight() / 2) - (fontLarge.lineHeight() * 0.75);
+ int16_t signalX = width() - signalW;
+ drawSignalIndicator(signalX, signalY, signalW, signalH, signal);
+ }
+ // Otherwise, print "hops away" info, if available
+ else if (hopsAway != CardInfo::HOPS_UNKNOWN) {
+ std::string hopString = to_string(node->hops_away);
+ hopString += " Hop";
+ if (node->hops_away != 1)
+ hopString += "s"; // Append s for "Hops", rather than "Hop"
+
+ printAt(width() - 1, lineAY, hopString, RIGHT, MIDDLE);
+ }
+
+ // Print the long name, cropping to prevent overflow onto the right-side info
+ setCrop(0, 0, dividerX - 1, height());
+ printAt(0, lineBY, longName, LEFT, MIDDLE);
+
+ // GFX effect: "hatch" the right edge of longName area
+ // If a longName has been cropped, it will appear to fade out,
+ // creating a soft barrier with the right-side info
+ const int16_t hatchLeft = dividerX - 1 - (fontSmall.lineHeight());
+ const int16_t hatchWidth = fontSmall.lineHeight();
+ hatchRegion(hatchLeft, cardTopY, hatchWidth, cardH, 2, WHITE);
+
+ // Prepare to draw the next card
+ resetCrop();
+ cardTopY += cardH;
+
+ // Once we've run out of screen, stop drawing cards
+ // Depending on tiles / rotation, this may be before we hit maxCards
+ if (cardTopY > height()) {
+ break;
+ }
+ }
+}
+
+// Draw element: a "mobile phone" style signal indicator
+// We will calculate values as floats, then "rasterize" at the last moment, relative to x and w, etc
+// This prevents issues with premature rounding when rendering tiny elements
+void InkHUD::NodeListApplet::drawSignalIndicator(int16_t x, int16_t y, uint16_t w, uint16_t h, SignalStrength strength)
+{
+
+ /*
+ +-------------------------------------------+
+ | |
+ | |
+ | barHeightRelative=1.0
+ | +--+ ^ |
+ | gutterW +--+ | | | |
+ | <--> +--+ | | | | | |
+ | +--+ | | | | | | | |
+ | | | | | | | | | | |
+ | <-> +--+ +--+ +--+ +--+ v |
+ | paddingW ^ |
+ | paddingH | |
+ | v |
+ +-------------------------------------------+
+ */
+
+ constexpr float paddingW = 0.1; // Either side
+ constexpr float paddingH = 0.1; // Above and below
+ constexpr float gutterX = 0.1; // Between bars
+
+ constexpr float barHRel[] = {0.3, 0.5, 0.7, 1.0}; // Heights of the signal bars, relative to the talleest
+ constexpr uint8_t barCount = 4; // How many bars we draw. Reference only: changing value won't change the count.
+
+ // Dynamically calculate the width of the bars, and height of the rightmost, relative to other dimensions
+ float barW = (1.0 - (paddingW + ((barCount - 1) * gutterX) + paddingW)) / barCount;
+ float barHMax = 1.0 - (paddingH + paddingH);
+
+ // Draw signal bar rectangles, then placeholder lines once strength reached
+ for (uint8_t i = 0; i < barCount; i++) {
+ // Co-ords for this specific bar
+ float barH = barHMax * barHRel[i];
+ float barX = paddingW + (i * (gutterX + barW));
+ float barY = paddingH + (barHMax - barH);
+
+ // Rasterize to px coords at the last moment
+ int16_t rX = (x + (w * barX)) + 0.5;
+ int16_t rY = (y + (h * barY)) + 0.5;
+ uint16_t rW = (w * barW) + 0.5;
+ uint16_t rH = (h * barH) + 0.5;
+
+ // Draw signal bars, until we are displaying the correct "signal strength", then just draw placeholder lines
+ if (i <= strength)
+ drawRect(rX, rY, rW, rH, BLACK);
+ else {
+ // Just draw a placeholder line
+ float lineY = barY + barH;
+ uint16_t rLineY = (y + (h * lineY)) + 0.5; // Rasterize
+ drawLine(rX, rLineY, rX + rW - 1, rLineY, BLACK);
+ }
+ }
+}
+
+#endif
\ No newline at end of file
diff --git a/src/graphics/niche/InkHUD/Applets/Bases/NodeList/NodeListApplet.h b/src/graphics/niche/InkHUD/Applets/Bases/NodeList/NodeListApplet.h
new file mode 100644
index 000000000..670dd9e9a
--- /dev/null
+++ b/src/graphics/niche/InkHUD/Applets/Bases/NodeList/NodeListApplet.h
@@ -0,0 +1,71 @@
+#ifdef MESHTASTIC_INCLUDE_INKHUD
+
+/*
+
+Base class for Applets which display a list of nodes
+Used by the "Recents" and "Heard" applets. Possibly more in future?
+
+ +-------------------------------+
+ | | |
+ | SHRT . | | |
+ | Long name 50km |
+ | |
+ | ABCD 2 Hops |
+ | abcdedfghijk 30km |
+ | |
+ +-------------------------------+
+
+*/
+
+#pragma once
+
+#include "configuration.h"
+
+#include "graphics/niche/InkHUD/Applet.h"
+
+namespace NicheGraphics::InkHUD
+{
+
+class NodeListApplet : public Applet, public MeshModule
+{
+ protected:
+ // Info used to draw one card to the node list
+ struct CardInfo {
+ static constexpr uint8_t HOPS_UNKNOWN = -1;
+ static constexpr uint32_t DISTANCE_UNKNOWN = -1;
+
+ NodeNum nodeNum = 0;
+ SignalStrength signal = SignalStrength::SIGNAL_UNKNOWN;
+ uint32_t distanceMeters = DISTANCE_UNKNOWN;
+ uint8_t hopsAway = HOPS_UNKNOWN; // Unknown
+ };
+
+ public:
+ NodeListApplet(const char *name);
+ void onRender() override;
+
+ // MeshModule overrides
+ virtual bool wantPacket(const meshtastic_MeshPacket *p) override;
+ virtual ProcessMessage handleReceived(const meshtastic_MeshPacket &mp) override;
+
+ protected:
+ virtual void handleParsed(CardInfo c) = 0; // Pass extracted info from a new packet to derived class, for sorting and storage
+ virtual std::string getHeaderText() = 0; // Title for the applet's header. Todo: get this info another way?
+
+ uint8_t maxCards(); // Calculate the maximum number of cards an applet could ever display
+
+ std::deque cards; // Derived applet places cards here, for this base applet to render
+
+ private:
+ // UI element: a "mobile phone" style signal indicator
+ void drawSignalIndicator(int16_t x, int16_t y, uint16_t w, uint16_t h, SignalStrength signal);
+
+ // Dimensions for drawing
+ // Used for render, and also for maxCards calc
+ const uint8_t cardMarginH = fontSmall.lineHeight() / 2; // Gap between cards
+ const uint16_t cardH = fontLarge.lineHeight() + fontSmall.lineHeight() + cardMarginH; // Height of card
+};
+
+} // namespace NicheGraphics::InkHUD
+
+#endif
\ No newline at end of file
diff --git a/src/graphics/niche/InkHUD/Applets/Examples/BasicExample/BasicExampleApplet.cpp b/src/graphics/niche/InkHUD/Applets/Examples/BasicExample/BasicExampleApplet.cpp
new file mode 100644
index 000000000..17458ab96
--- /dev/null
+++ b/src/graphics/niche/InkHUD/Applets/Examples/BasicExample/BasicExampleApplet.cpp
@@ -0,0 +1,14 @@
+#ifdef MESHTASTIC_INCLUDE_INKHUD
+
+#include "./BasicExampleApplet.h"
+
+using namespace NicheGraphics;
+
+// All drawing happens here
+// Our basic example doesn't do anything useful. It just passively prints some text.
+void InkHUD::BasicExampleApplet::onRender()
+{
+ print("Hello, World!");
+}
+
+#endif
\ No newline at end of file
diff --git a/src/graphics/niche/InkHUD/Applets/Examples/BasicExample/BasicExampleApplet.h b/src/graphics/niche/InkHUD/Applets/Examples/BasicExample/BasicExampleApplet.h
new file mode 100644
index 000000000..aed63cdc8
--- /dev/null
+++ b/src/graphics/niche/InkHUD/Applets/Examples/BasicExample/BasicExampleApplet.h
@@ -0,0 +1,36 @@
+#ifdef MESHTASTIC_INCLUDE_INKHUD
+
+/*
+
+A bare-minimum example of an InkHUD applet.
+Only prints Hello World.
+
+In variants//nicheGraphics.h:
+
+ - include this .h file
+ - add the following line of code:
+ windowManager->addApplet("Basic", new InkHUD::BasicExampleApplet);
+
+*/
+
+#pragma once
+
+#include "configuration.h"
+
+#include "graphics/niche/InkHUD/Applet.h"
+
+namespace NicheGraphics::InkHUD
+{
+
+class BasicExampleApplet : public Applet
+{
+ public:
+ // You must have an onRender() method
+ // All drawing happens here
+
+ void onRender() override;
+};
+
+} // namespace NicheGraphics::InkHUD
+
+#endif
\ No newline at end of file
diff --git a/src/graphics/niche/InkHUD/Applets/Examples/NewMsgExample/NewMsgExampleApplet.cpp b/src/graphics/niche/InkHUD/Applets/Examples/NewMsgExample/NewMsgExampleApplet.cpp
new file mode 100644
index 000000000..e0b2a4238
--- /dev/null
+++ b/src/graphics/niche/InkHUD/Applets/Examples/NewMsgExample/NewMsgExampleApplet.cpp
@@ -0,0 +1,54 @@
+#ifdef MESHTASTIC_INCLUDE_INKHUD
+
+#include "./NewMsgExampleApplet.h"
+
+using namespace NicheGraphics;
+
+// We configured MeshModule API to call this method when we receive a new text message
+ProcessMessage InkHUD::NewMsgExampleApplet::handleReceived(const meshtastic_MeshPacket &mp)
+{
+
+ // Abort if applet fully deactivated
+ if (!isActive())
+ return ProcessMessage::CONTINUE;
+
+ // Check that this is an incoming message
+ // Outgoing messages (sent by us) will also call handleReceived
+
+ if (!isFromUs(&mp)) {
+ // Store the sender's nodenum
+ // We need to keep this information, so we can re-use it anytime render() is called
+ haveMessage = true;
+ fromWho = mp.from;
+
+ // Tell InkHUD that we have something new to show on the screen
+ requestUpdate();
+ }
+
+ // Tell MeshModule API to continue informing other firmware components about this message
+ // We're not the only component which is interested in new text messages
+ return ProcessMessage::CONTINUE;
+}
+
+// All drawing happens here
+// We can trigger a render by calling requestUpdate()
+// Render might be called by some external source
+// We should always be ready to draw
+void InkHUD::NewMsgExampleApplet::onRender()
+{
+ setFont(fontSmall);
+
+ printAt(0, 0, "Example: NewMsg", LEFT, TOP); // Print top-left corner of text at (0,0)
+
+ int16_t centerX = X(0.5); // Same as width() / 2
+ int16_t centerY = Y(0.5); // Same as height() / 2
+
+ if (haveMessage) {
+ printAt(centerX, centerY, "New Message", CENTER, BOTTOM);
+ printAt(centerX, centerY, "From: " + hexifyNodeNum(fromWho), CENTER, TOP);
+ } else {
+ printAt(centerX, centerY, "No Message", CENTER, MIDDLE); // Place center of string at (centerX, centerY)
+ }
+}
+
+#endif
\ No newline at end of file
diff --git a/src/graphics/niche/InkHUD/Applets/Examples/NewMsgExample/NewMsgExampleApplet.h b/src/graphics/niche/InkHUD/Applets/Examples/NewMsgExample/NewMsgExampleApplet.h
new file mode 100644
index 000000000..edfb211d7
--- /dev/null
+++ b/src/graphics/niche/InkHUD/Applets/Examples/NewMsgExample/NewMsgExampleApplet.h
@@ -0,0 +1,61 @@
+#ifdef MESHTASTIC_INCLUDE_INKHUD
+
+/*
+
+An example of an InkHUD applet.
+Tells us when a new text message arrives.
+
+This applet makes use of the MeshModule API to detect new messages,
+which is a general part of the Meshtastic firmware, and not part of InkHUD.
+
+In variants//nicheGraphics.h:
+
+ - include this .h file
+ - add the following line of code:
+ windowManager->addApplet("New Msg", new InkHUD::NewMsgExampleApplet);
+
+*/
+
+#pragma once
+
+#include "configuration.h"
+
+#include "graphics/niche/InkHUD/Applet.h"
+
+#include "mesh/SinglePortModule.h"
+
+namespace NicheGraphics::InkHUD
+{
+
+class NewMsgExampleApplet : public Applet, public SinglePortModule
+{
+ public:
+ // The MeshModule API requires us to have a constructor, to specify that we're interested in Text Messages.
+ NewMsgExampleApplet() : SinglePortModule("NewMsgExampleApplet", meshtastic_PortNum_TEXT_MESSAGE_APP) {}
+
+ // All drawing happens here
+ void onRender() override;
+
+ // Your applet might also want to use some of these
+ // Useful for setting up or tidying up
+
+ /*
+ void onActivate(); // When started
+ void onDeactivate(); // When stopped
+ void onForeground(); // When shown by short-press
+ void onBackground(); // When hidden by short-press
+ */
+
+ private:
+ // Called when we receive new text messages
+ // Part of the MeshModule API
+ ProcessMessage handleReceived(const meshtastic_MeshPacket &mp) override;
+
+ // Store info from handleReceived
+ bool haveMessage = false;
+ NodeNum fromWho;
+};
+
+} // namespace NicheGraphics::InkHUD
+
+#endif
\ No newline at end of file
diff --git a/src/graphics/niche/InkHUD/Applets/System/BatteryIcon/BatteryIconApplet.cpp b/src/graphics/niche/InkHUD/Applets/System/BatteryIcon/BatteryIconApplet.cpp
new file mode 100644
index 000000000..e4432a7c2
--- /dev/null
+++ b/src/graphics/niche/InkHUD/Applets/System/BatteryIcon/BatteryIconApplet.cpp
@@ -0,0 +1,107 @@
+#ifdef MESHTASTIC_INCLUDE_INKHUD
+
+#include "./BatteryIconApplet.h"
+
+using namespace NicheGraphics;
+
+void InkHUD::BatteryIconApplet::onActivate()
+{
+ // Show at boot, if user has previously enabled the feature
+ if (settings.optionalFeatures.batteryIcon)
+ bringToForeground();
+
+ // Register to our have BatteryIconApplet::onPowerStatusUpdate method called when new power info is available
+ // This happens whether or not the battery icon feature is enabled
+ powerStatusObserver.observe(&powerStatus->onNewStatus);
+}
+
+void InkHUD::BatteryIconApplet::onDeactivate()
+{
+ // Stop having onPowerStatusUpdate called
+ powerStatusObserver.unobserve(&powerStatus->onNewStatus);
+}
+
+// We handle power status' even when the feature is disabled,
+// so that we have up to date data ready if the feature is enabled later.
+// Otherwise could be 30s before new status update, with weird battery value displayed
+int InkHUD::BatteryIconApplet::onPowerStatusUpdate(const meshtastic::Status *status)
+{
+ // System applets are always active
+ assert(isActive());
+
+ // This method should only receive power statuses
+ // If we get a different type of status, something has gone weird elsewhere
+ assert(status->getStatusType() == STATUS_TYPE_POWER);
+
+ meshtastic::PowerStatus *powerStatus = (meshtastic::PowerStatus *)status;
+
+ // Get the new state of charge %, and round to the nearest 10%
+ uint8_t newSocRounded = ((powerStatus->getBatteryChargePercent() + 5) / 10) * 10;
+
+ // If rounded value has changed, trigger a display update
+ // It's okay to requestUpdate before we store the new value, as the update won't run until next loop()
+ // Don't trigger an update if the feature is disabled
+ if (this->socRounded != newSocRounded && settings.optionalFeatures.batteryIcon)
+ requestUpdate();
+
+ // Store the new value
+ this->socRounded = newSocRounded;
+
+ return 0; // Tell Observable to continue informing other observers
+}
+
+void InkHUD::BatteryIconApplet::onRender()
+{
+ // Fill entire tile
+ // - size of icon controlled by size of tile
+ int16_t l = 0;
+ int16_t t = 0;
+ uint16_t w = width();
+ int16_t h = height();
+
+ // Clear the region beneath the tile
+ // Most applets are drawing onto an empty frame buffer and don't need to do this
+ // We do need to do this with the battery though, as it is an "overlay"
+ fillRect(l, t, w, h, WHITE);
+
+ // Vertical centerline
+ const int16_t m = t + (h / 2);
+
+ // =====================
+ // Draw battery outline
+ // =====================
+
+ // Positive terminal "bump"
+ const int16_t &bumpL = l;
+ const uint16_t bumpH = h / 2;
+ const int16_t bumpT = m - (bumpH / 2);
+ constexpr uint16_t bumpW = 2;
+ fillRect(bumpL, bumpT, bumpW, bumpH, BLACK);
+
+ // Main body of battery
+ const int16_t bodyL = bumpL + bumpW;
+ const int16_t &bodyT = t;
+ const int16_t &bodyH = h;
+ const int16_t bodyW = w - bumpW;
+ drawRect(bodyL, bodyT, bodyW, bodyH, BLACK);
+
+ // Erase join between bump and body
+ drawLine(bodyL, bumpT, bodyL, bumpT + bumpH - 1, WHITE);
+
+ // ===================
+ // Draw battery level
+ // ===================
+
+ constexpr int16_t slicePad = 2;
+ const int16_t sliceL = bodyL + slicePad;
+ const int16_t sliceT = bodyT + slicePad;
+ const uint16_t sliceH = bodyH - (slicePad * 2);
+ uint16_t sliceW = bodyW - (slicePad * 2);
+
+ sliceW = (sliceW * socRounded) / 100; // Apply percentage
+
+ hatchRegion(sliceL, sliceT, sliceW, sliceH, 2, BLACK);
+ drawRect(sliceL, sliceT, sliceW, sliceH, BLACK);
+}
+
+#endif
\ No newline at end of file
diff --git a/src/graphics/niche/InkHUD/Applets/System/BatteryIcon/BatteryIconApplet.h b/src/graphics/niche/InkHUD/Applets/System/BatteryIcon/BatteryIconApplet.h
new file mode 100644
index 000000000..765ca073f
--- /dev/null
+++ b/src/graphics/niche/InkHUD/Applets/System/BatteryIcon/BatteryIconApplet.h
@@ -0,0 +1,41 @@
+#ifdef MESHTASTIC_INCLUDE_INKHUD
+
+/*
+
+This applet floats top-left, giving a graphical representation of battery remaining
+It should be optional, enabled by the on-screen menu
+
+*/
+
+#pragma once
+
+#include "configuration.h"
+
+#include "graphics/niche/InkHUD/Applet.h"
+
+#include "PowerStatus.h"
+
+namespace NicheGraphics::InkHUD
+{
+
+class BatteryIconApplet : public Applet
+{
+ public:
+ void onRender() override;
+
+ void onActivate() override;
+ void onDeactivate() override;
+
+ int onPowerStatusUpdate(const meshtastic::Status *status); // Called when new info about battery is available
+
+ protected:
+ // Get informed when new information about the battery is available (via onPowerStatusUpdate method)
+ CallbackObserver powerStatusObserver =
+ CallbackObserver(this, &BatteryIconApplet::onPowerStatusUpdate);
+
+ uint8_t socRounded = 0; // Battery state of charge, rounded to nearest 10%
+};
+
+} // namespace NicheGraphics::InkHUD
+
+#endif
\ No newline at end of file
diff --git a/src/graphics/niche/InkHUD/Applets/System/Logo/LogoApplet.cpp b/src/graphics/niche/InkHUD/Applets/System/Logo/LogoApplet.cpp
new file mode 100644
index 000000000..cc24417ab
--- /dev/null
+++ b/src/graphics/niche/InkHUD/Applets/System/Logo/LogoApplet.cpp
@@ -0,0 +1,108 @@
+#ifdef MESHTASTIC_INCLUDE_INKHUD
+
+#include "./LogoApplet.h"
+
+using namespace NicheGraphics;
+
+InkHUD::LogoApplet::LogoApplet() : concurrency::OSThread("LogoApplet")
+{
+ // Don't autostart the runOnce() timer
+ OSThread::disable();
+
+ // Grab the WindowManager singleton, for convenience
+ windowManager = WindowManager::getInstance();
+}
+
+void InkHUD::LogoApplet::onRender()
+{
+ // Size of the region which the logo should "scale to fit"
+ uint16_t logoWLimit = X(0.8);
+ uint16_t logoHLimit = Y(0.5);
+
+ // Get the max width and height we can manage within the region, while still maintaining aspect ratio
+ uint16_t logoW = getLogoWidth(logoWLimit, logoHLimit);
+ uint16_t logoH = getLogoHeight(logoWLimit, logoHLimit);
+
+ // Where to place the center of the logo
+ int16_t logoCX = X(0.5);
+ int16_t logoCY = Y(0.5 - 0.05);
+
+ drawLogo(logoCX, logoCY, logoW, logoH);
+
+ if (!textLeft.empty()) {
+ setFont(fontSmall);
+ printAt(0, 0, textLeft, LEFT, TOP);
+ }
+
+ if (!textRight.empty()) {
+ setFont(fontSmall);
+ printAt(X(1), 0, textRight, RIGHT, TOP);
+ }
+
+ if (!textTitle.empty()) {
+ int16_t logoB = logoCY + (logoH / 2); // Bottom of the logo
+ setFont(fontTitle);
+ printAt(X(0.5), logoB + Y(0.1), textTitle, CENTER, TOP);
+ }
+}
+
+void InkHUD::LogoApplet::onForeground()
+{
+ // If another applet has locked the display, ask it to exit
+ Applet *other = windowManager->whoLocked();
+ if (other != nullptr)
+ other->sendToBackground();
+
+ windowManager->claimFullscreen(this); // Take ownership of fullscreen tile
+ windowManager->lock(this); // Prevent other applets from requesting updates
+}
+
+void InkHUD::LogoApplet::onBackground()
+{
+ OSThread::disable(); // Disable auto-dismiss timer, in case applet was dismissed early (sendToBackground from outside class)
+
+ windowManager->releaseFullscreen(); // Relinquish ownership of fullscreen tile
+ windowManager->unlock(this); // Allow normal user applet update requests to resume
+
+ // Need to force an update, as a polite request wouldn't be honored, seeing how we are now in the background
+ // Usually, onBackground is followed by another applet's onForeground (which requests update), but not in this case
+ windowManager->forceUpdate(EInk::UpdateTypes::FULL);
+}
+
+int32_t InkHUD::LogoApplet::runOnce()
+{
+ LOG_DEBUG("Sent to background by timer");
+ sendToBackground();
+ return OSThread::disable();
+}
+
+// Begin displaying the screen which is shown at startup
+// Suggest EInk::await after calling this method
+void InkHUD::LogoApplet::showBootScreen()
+{
+ OSThread::setIntervalFromNow(8 * 1000UL);
+ OSThread::enabled = true;
+
+ textLeft = "";
+ textRight = "";
+ textTitle = xstr(APP_VERSION_SHORT);
+ fontTitle = fontSmall;
+
+ bringToForeground();
+ requestUpdate(Drivers::EInk::UpdateTypes::FULL); // Already requested, just upgrading to FULL
+}
+
+// Begin displaying the screen which is shown at shutdown
+// Needs EInk::await after calling this method, to ensure display updates before shutdown
+void InkHUD::LogoApplet::showShutdownScreen()
+{
+ textLeft = "";
+ textRight = "";
+ textTitle = owner.short_name;
+ fontTitle = fontLarge;
+
+ bringToForeground();
+ requestUpdate(Drivers::EInk::UpdateTypes::FULL); // Already requested, just upgrading to FULL
+}
+
+#endif
\ No newline at end of file
diff --git a/src/graphics/niche/InkHUD/Applets/System/Logo/LogoApplet.h b/src/graphics/niche/InkHUD/Applets/System/Logo/LogoApplet.h
new file mode 100644
index 000000000..aa1bf8b2c
--- /dev/null
+++ b/src/graphics/niche/InkHUD/Applets/System/Logo/LogoApplet.h
@@ -0,0 +1,47 @@
+#ifdef MESHTASTIC_INCLUDE_INKHUD
+
+/*
+
+ Shows the Meshtastic logo fullscreen, with accompanying text
+ Used for boot and shutdown
+
+*/
+
+#pragma once
+
+#include "configuration.h"
+
+#include "concurrency/OSThread.h"
+#include "graphics/niche/InkHUD/Applet.h"
+
+namespace NicheGraphics::InkHUD
+{
+
+class LogoApplet : public Applet, public concurrency::OSThread
+{
+ public:
+ LogoApplet();
+ void onRender() override;
+ void onForeground() override;
+ void onBackground() override;
+
+ // Note: interacting directly with an applet like this is non-standard
+ // Only permitted because this is a "system applet", which has special behavior and interacts directly with WindowManager
+
+ void showBootScreen();
+ void showShutdownScreen();
+
+ protected:
+ int32_t runOnce() override;
+
+ std::string textLeft;
+ std::string textRight;
+ std::string textTitle;
+ AppletFont fontTitle;
+
+ WindowManager *windowManager = nullptr; // For convenience
+};
+
+} // namespace NicheGraphics::InkHUD
+
+#endif
\ No newline at end of file
diff --git a/src/graphics/niche/InkHUD/Applets/System/Menu/MenuAction.h b/src/graphics/niche/InkHUD/Applets/System/Menu/MenuAction.h
new file mode 100644
index 000000000..6950bb110
--- /dev/null
+++ b/src/graphics/niche/InkHUD/Applets/System/Menu/MenuAction.h
@@ -0,0 +1,38 @@
+#ifdef MESHTASTIC_INCLUDE_INKHUD
+
+/*
+
+Set of end-point actions for the Menu Applet
+
+Added as menu entries in MenuApplet::showPage
+Behaviors assigned in MenuApplet::execute
+
+*/
+
+#pragma once
+
+#include "configuration.h"
+
+namespace NicheGraphics::InkHUD
+{
+
+enum MenuAction {
+ NO_ACTION,
+ SEND_NODEINFO,
+ SEND_POSITION,
+ SHUTDOWN,
+ NEXT_TILE,
+ TOGGLE_APPLET,
+ ACTIVATE_APPLETS, // Todo: remove? Possible redundant, handled by TOGGLE_APPLET?
+ TOGGLE_AUTOSHOW_APPLET,
+ SET_RECENTS,
+ ROTATE,
+ LAYOUT,
+ TOGGLE_BATTERY_ICON,
+ TOGGLE_NOTIFICATIONS,
+ TOGGLE_BACKLIGHT,
+};
+
+} // namespace NicheGraphics::InkHUD
+
+#endif
\ No newline at end of file
diff --git a/src/graphics/niche/InkHUD/Applets/System/Menu/MenuApplet.cpp b/src/graphics/niche/InkHUD/Applets/System/Menu/MenuApplet.cpp
new file mode 100644
index 000000000..d24ae59a5
--- /dev/null
+++ b/src/graphics/niche/InkHUD/Applets/System/Menu/MenuApplet.cpp
@@ -0,0 +1,612 @@
+#ifdef MESHTASTIC_INCLUDE_INKHUD
+
+#include "./MenuApplet.h"
+
+#include "PowerStatus.h"
+#include "RTC.h"
+
+using namespace NicheGraphics;
+
+static constexpr uint8_t MENU_TIMEOUT_SEC = 60; // How many seconds before menu auto-closes
+
+// Options for the "Recents" menu
+// These are offered to users as possible values for settings.recentlyActiveSeconds
+static constexpr uint8_t RECENTS_OPTIONS_MINUTES[] = {2, 5, 10, 30, 60, 120};
+
+InkHUD::MenuApplet::MenuApplet() : concurrency::OSThread("MenuApplet")
+{
+ // No timer tasks at boot
+ OSThread::disable();
+}
+
+void InkHUD::MenuApplet::onActivate()
+{
+ // Grab pointers to some singleton components which the menu interacts with
+ // We could do this every time we needed them, in place,
+ // but this just makes the code tidier
+
+ this->windowManager = WindowManager::getInstance();
+
+ // Note: don't get instance if we're not actually using the backlight,
+ // or else you will unintentionally instantiate it
+ if (settings.optionalMenuItems.backlight) {
+ backlight = Drivers::LatchingBacklight::getInstance();
+ }
+}
+
+void InkHUD::MenuApplet::onForeground()
+{
+ // We do need this before we render, but we can optimize by just calculating it once now
+ systemInfoPanelHeight = getSystemInfoPanelHeight();
+
+ // Display initial menu page
+ showPage(MenuPage::ROOT);
+
+ // If device has a backlight which isn't controlled by aux button:
+ // backlight on always when menu opens.
+ // Courtesy to T-Echo users who removed the capacitive touch button
+ if (settings.optionalMenuItems.backlight) {
+ assert(backlight);
+ if (!backlight->isOn())
+ backlight->peek();
+ }
+
+ // Prevent user applets requested update while menu is open
+ windowManager->lock(this);
+
+ // Begin the auto-close timeout
+ OSThread::setIntervalFromNow(MENU_TIMEOUT_SEC * 1000UL);
+ OSThread::enabled = true;
+
+ // Upgrade the refresh to FAST, for guaranteed responsiveness
+ windowManager->forceUpdate(EInk::UpdateTypes::FAST);
+}
+
+void InkHUD::MenuApplet::onBackground()
+{
+ // If device has a backlight which isn't controlled by aux button:
+ // Item in options submenu allows keeping backlight on after menu is closed
+ // If this item is deselected we will turn backlight off again, now that menu is closing
+ if (settings.optionalMenuItems.backlight) {
+ assert(backlight);
+ if (!backlight->isLatched())
+ backlight->off();
+ }
+
+ // Stop the auto-timeout
+ OSThread::disable();
+
+ // Resume normal rendering and button behavior of user applets
+ windowManager->unlock(this);
+
+ // Restore the user applet whose tile we borrowed
+ if (borrowedTileOwner)
+ borrowedTileOwner->bringToForeground();
+ Tile *t = getTile();
+ t->assignApplet(borrowedTileOwner); // Break our link with the tile, (and relink it with real owner, if it had one)
+ borrowedTileOwner = nullptr;
+
+ // Need to force an update, as a polite request wouldn't be honored, seeing how we are now in the background
+ // We're only updating here to ugrade from UNSPECIFIED to FAST, to ensure responsiveness when exiting menu
+ windowManager->forceUpdate(EInk::UpdateTypes::FAST);
+}
+
+// Open the menu
+// Parameter specifies which user-tile the menu will use
+// The user applet originally on this tile will be restored when the menu closes
+void InkHUD::MenuApplet::show(Tile *t)
+{
+ // Remember who *really* owns this tile
+ borrowedTileOwner = t->getAssignedApplet();
+
+ // Hide the owner, if it is a valid applet
+ if (borrowedTileOwner)
+ borrowedTileOwner->sendToBackground();
+
+ // Break the owner's link with tile
+ // Relink it to menu applet
+ t->assignApplet(this);
+
+ // Show menu
+ bringToForeground();
+}
+
+// Auto-exit the menu applet after a period of inactivity
+// The values shown on the root menu are only a snapshot: they are not re-rendered while the menu remains open.
+// By exiting the menu, we prevent users mistakenly believing that the data will update.
+int32_t InkHUD::MenuApplet::runOnce()
+{
+ // runOnce's interval is pushed back when a button is pressed
+ // If we do actually run, it means no button input occurred within MENU_TIMEOUT_SEC,
+ // so we close the menu.
+ showPage(EXIT);
+
+ // Timer should disable after firing
+ // This is redundant, as onBackground() will also disable
+ return OSThread::disable();
+}
+
+// Perform action for a menu item, then change page
+// Behaviors for MenuActions are defined here
+void InkHUD::MenuApplet::execute(MenuItem item)
+{
+ // Perform an action
+ // ------------------
+ switch (item.action) {
+
+ // Open a submenu without performing any action
+ // Also handles exit
+ case NO_ACTION:
+ break;
+
+ case NEXT_TILE:
+ // Note performed manually;
+ // WindowManager::nextTile is raised by aux button press only, and will interact poorly with the menu
+ settings.userTiles.focused = (settings.userTiles.focused + 1) % settings.userTiles.count;
+ windowManager->changeLayout();
+ cursor = 0; // No menu item selected, for quick exit after tile swap
+ cursorShown = false;
+ break;
+
+ case ROTATE:
+ settings.rotation = (settings.rotation + 1) % 4;
+ windowManager->changeLayout();
+ // requestUpdate(Drivers::EInk::UpdateTypes::FULL); // Would update regardless; just selecting FULL
+ break;
+
+ case LAYOUT:
+ // Todo: smarter incrementing of tile count
+ settings.userTiles.count++;
+
+ if (settings.userTiles.count == 3) // Skip 3 tiles: not done yet
+ settings.userTiles.count++;
+
+ if (settings.userTiles.count > settings.userTiles.maxCount) // Loop around if tile count now too high
+ settings.userTiles.count = 1;
+
+ windowManager->changeLayout();
+ // requestUpdate(Drivers::EInk::UpdateTypes::FULL); // Would update regardless; just selecting FULL
+ break;
+
+ case TOGGLE_APPLET:
+ settings.userApplets.active[cursor] = !settings.userApplets.active[cursor];
+ windowManager->changeActivatedApplets();
+ // requestUpdate(Drivers::EInk::UpdateTypes::FULL); // Select FULL, seeing how this action doesn't auto exit
+ break;
+
+ case ACTIVATE_APPLETS:
+ // Todo: remove this action? Already handled by TOGGLE_APPLET?
+ windowManager->changeActivatedApplets();
+ break;
+
+ case TOGGLE_AUTOSHOW_APPLET:
+ // Toggle settings.userApplets.autoshow[] value, via MenuItem::checkState pointer set in populateAutoshowPage()
+ *items.at(cursor).checkState = !(*items.at(cursor).checkState);
+ break;
+
+ case TOGGLE_NOTIFICATIONS:
+ settings.optionalFeatures.notifications = !settings.optionalFeatures.notifications;
+ break;
+
+ case SET_RECENTS:
+ // Set value of settings.recentlyActiveSeconds
+ // Uses menu cursor to read RECENTS_OPTIONS_MINUTES array (defined at top of this file)
+ assert(cursor < sizeof(RECENTS_OPTIONS_MINUTES) / sizeof(RECENTS_OPTIONS_MINUTES[0]));
+ settings.recentlyActiveSeconds = RECENTS_OPTIONS_MINUTES[cursor] * 60; // Menu items are in minutes
+ break;
+
+ case SHUTDOWN:
+ LOG_INFO("Shutting down from menu");
+ power->shutdown();
+ // Menu is then sent to background via onShutdown
+ break;
+
+ case TOGGLE_BATTERY_ICON:
+ windowManager->toggleBatteryIcon();
+ break;
+
+ case TOGGLE_BACKLIGHT:
+ // Note: backlight is already on in this situation
+ // We're marking that it should *remain* on once menu closes
+ assert(backlight);
+ if (backlight->isLatched())
+ backlight->off();
+ else
+ backlight->latch();
+ break;
+
+ default:
+ LOG_WARN("Action not implemented");
+ }
+
+ // Move to next page, as defined for the MenuItem
+ showPage(item.nextPage);
+}
+
+// Display a new page of MenuItems
+// May reload same page, or exit menu applet entirely
+// Fills the MenuApplet::items vector
+void InkHUD::MenuApplet::showPage(MenuPage page)
+{
+ items.clear();
+
+ switch (page) {
+ case ROOT:
+ // Optional: next applet
+ if (settings.optionalMenuItems.nextTile && settings.userTiles.count > 1)
+ items.push_back(MenuItem("Next Tile", MenuAction::NEXT_TILE, MenuPage::ROOT)); // Only if multiple applets shown
+
+ // items.push_back(MenuItem("Send", MenuPage::SEND)); // TODO
+ items.push_back(MenuItem("Options", MenuPage::OPTIONS));
+ // items.push_back(MenuItem("Display Off", MenuPage::EXIT)); // TODO
+ items.push_back(MenuItem("Save & Shutdown", MenuAction::SHUTDOWN));
+ items.push_back(MenuItem("Exit", MenuPage::EXIT));
+ break;
+
+ case SEND:
+ items.push_back(MenuItem("Send Message", MenuPage::EXIT));
+ items.push_back(MenuItem("Send NodeInfo", MenuAction::SEND_NODEINFO));
+ items.push_back(MenuItem("Send Position", MenuAction::SEND_POSITION));
+ items.push_back(MenuItem("Exit", MenuPage::EXIT));
+ break;
+
+ case OPTIONS:
+ // Optional: backlight
+ if (settings.optionalMenuItems.backlight) {
+ assert(backlight);
+ items.push_back(MenuItem(backlight->isLatched() ? "Backlight Off" : "Keep Backlight On", // Label
+ MenuAction::TOGGLE_BACKLIGHT, // Action
+ MenuPage::EXIT // Exit once complete
+ ));
+ }
+
+ items.push_back(MenuItem("Applets", MenuPage::APPLETS));
+ items.push_back(MenuItem("Auto-show", MenuPage::AUTOSHOW));
+ items.push_back(MenuItem("Recents Duration", MenuPage::RECENTS));
+ if (settings.userTiles.maxCount > 1)
+ items.push_back(MenuItem("Layout", MenuAction::LAYOUT, MenuPage::OPTIONS));
+ items.push_back(MenuItem("Rotate", MenuAction::ROTATE, MenuPage::OPTIONS));
+ items.push_back(MenuItem("Notifications", MenuAction::TOGGLE_NOTIFICATIONS, MenuPage::OPTIONS,
+ &settings.optionalFeatures.notifications));
+ items.push_back(
+ MenuItem("Battery Icon", MenuAction::TOGGLE_BATTERY_ICON, MenuPage::OPTIONS, &settings.optionalFeatures.batteryIcon));
+
+ // TODO - GPS and Wifi switches
+ /*
+ // Optional: has GPS
+ if (config.position.gps_mode == meshtastic_Config_PositionConfig_GpsMode_DISABLED)
+ items.push_back(MenuItem("Enable GPS", MenuPage::EXIT)); // TODO
+ if (config.position.gps_mode == meshtastic_Config_PositionConfig_GpsMode_ENABLED)
+ items.push_back(MenuItem("Disable GPS", MenuPage::EXIT)); // TODO
+
+ // Optional: using wifi
+ if (!config.bluetooth.enabled)
+ items.push_back(MenuItem("Enable Bluetooth", MenuPage::EXIT)); // TODO: escape hatch if wifi configured wrong
+ */
+
+ items.push_back(MenuItem("Exit", MenuPage::EXIT));
+ break;
+
+ case APPLETS:
+ populateAppletPage();
+ items.push_back(MenuItem("Exit", MenuAction::ACTIVATE_APPLETS));
+ break;
+
+ case AUTOSHOW:
+ populateAutoshowPage();
+ items.push_back(MenuItem("Exit", MenuPage::EXIT));
+ break;
+
+ case RECENTS:
+ populateRecentsPage();
+ break;
+
+ case EXIT:
+ sendToBackground(); // Menu applet dismissed, allow normal behavior to resume
+ // requestUpdate(Drivers::EInk::UpdateTypes::FULL);
+ break;
+
+ default:
+ LOG_WARN("Page not implemented");
+ }
+
+ // Reset the cursor, unless reloading same page
+ // (or now out-of-bounds)
+ if (page != currentPage || cursor >= items.size()) {
+ cursor = 0;
+
+ // ROOT menu has special handling: unselected at first, to emphasise the system info panel
+ if (page == ROOT)
+ cursorShown = false;
+ }
+
+ // Remember which page we are on now
+ currentPage = page;
+}
+
+void InkHUD::MenuApplet::onRender()
+{
+ if (items.size() == 0)
+ LOG_ERROR("Empty Menu");
+
+ // Testing only
+ setFont(fontSmall);
+
+ // Dimensions for the slots where we will draw menuItems
+ const float padding = 0.05;
+ const uint16_t itemH = fontSmall.lineHeight() * 2;
+ const int16_t itemW = width() - X(padding) - X(padding);
+ const int16_t itemL = X(padding);
+ const int16_t itemR = X(1 - padding);
+ int16_t itemT = 0; // Top (y px of current slot). Incremented as we draw. Adjusted to fit system info panel on ROOT menu.
+
+ // How many full menuItems will fit on screen
+ uint8_t slotCount = (height() - itemT) / itemH;
+
+ // System info panel at the top of the menu
+ // =========================================
+
+ uint16_t &siH = systemInfoPanelHeight; // System info - height. Calculated at onForeground
+ const uint8_t slotsObscured = ceilf(siH / (float)itemH); // How many slots are obscured by system info panel
+
+ // System info - top
+ // Remain at 0px, until cursor reaches bottom of screen, then begin to scroll off screen.
+ // This is the same behavior we expect from the non-root menus.
+ // Implementing this with the systemp panel is slightly annoying though,
+ // and required adding the MenuApplet::getSystemInfoPanelHeight method
+ int16_t siT;
+ if (cursor < slotCount - slotsObscured - 1) // (Minus 1: comparing zero based index with a count)
+ siT = 0;
+ else
+ siT = 0 - ((cursor - (slotCount - slotsObscured - 1)) * itemH);
+
+ // If showing ROOT menu,
+ // and the panel isn't yet scrolled off screen top
+ if (currentPage == ROOT) {
+ drawSystemInfoPanel(0, siT, width()); // Draw the panel.
+ itemT = max(siT + siH, 0); // Offset the first menu entry, so menu starts below the system info panel
+ }
+
+ // Draw menu items
+ // ===================
+
+ // Which item will be drawn to the top-most slot?
+ // Initially, this is the item 0, but may increase once we begin scrolling
+ uint8_t firstItem;
+ if (cursor < slotCount)
+ firstItem = 0;
+ else
+ firstItem = cursor - (slotCount - 1);
+
+ // Which item will be drawn to the bottom-most slot?
+ // This may be beyond the slot-count, to draw a partially off-screen item below the bottom-most slow
+ // This may be less than the slot-count, if we are reaching the end of the menuItems
+ uint8_t lastItem = min((uint8_t)firstItem + slotCount, (uint8_t)items.size() - 1);
+
+ // -- Loop: draw each (visible) menu item --
+ for (uint8_t i = firstItem; i <= lastItem; i++) {
+ // Grab the menuItem
+ MenuItem item = items.at(i);
+
+ // Center-line for the text
+ int16_t center = itemT + (itemH / 2);
+
+ if (cursorShown && i == cursor)
+ drawRect(itemL, itemT, itemW, itemH, BLACK);
+ printAt(itemL + X(padding), center, item.label, LEFT, MIDDLE);
+
+ // Testing only: circle instead of check box
+ if (item.checkState) {
+ const uint16_t cbWH = fontSmall.lineHeight(); // Checbox: width / height
+ const int16_t cbL = itemR - X(padding) - cbWH; // Checkbox: left
+ const int16_t cbT = center - (cbWH / 2); // Checkbox : top
+ // Checkbox ticked
+ if (*(item.checkState)) {
+ drawRect(cbL, cbT, cbWH, cbWH, BLACK);
+ // First point of tick: pen down
+ const int16_t t1Y = center;
+ const int16_t t1X = cbL + 3;
+ // Second point of tick: base
+ const int16_t t2Y = center + (cbWH / 2) - 2;
+ const int16_t t2X = cbL + (cbWH / 2);
+ // Third point of tick: end of tail
+ const int16_t t3Y = center - (cbWH / 2) - 2;
+ const int16_t t3X = cbL + cbWH + 2;
+ // Draw twice: faux bold
+ drawLine(t1X, t1Y, t2X, t2Y, BLACK);
+ drawLine(t2X, t2Y, t3X, t3Y, BLACK);
+ drawLine(t1X + 1, t1Y, t2X + 1, t2Y, BLACK);
+ drawLine(t2X + 1, t2Y, t3X + 1, t3Y, BLACK);
+ }
+ // Checkbox ticked
+ else
+ drawRect(cbL, cbT, cbWH, cbWH, BLACK);
+ }
+
+ // Increment the y value (top) as we go
+ itemT += itemH;
+ }
+}
+
+void InkHUD::MenuApplet::onButtonShortPress()
+{
+ // Push the auto-close timer back
+ OSThread::setIntervalFromNow(MENU_TIMEOUT_SEC * 1000UL);
+
+ // Move menu cursor to next entry, then update
+ if (cursorShown)
+ cursor = (cursor + 1) % items.size();
+ else
+ cursorShown = true;
+ requestUpdate(Drivers::EInk::UpdateTypes::FAST);
+}
+
+void InkHUD::MenuApplet::onButtonLongPress()
+{
+ // Push the auto-close timer back
+ OSThread::setIntervalFromNow(MENU_TIMEOUT_SEC * 1000UL);
+
+ if (cursorShown)
+ execute(items.at(cursor));
+ else
+ showPage(MenuPage::EXIT); // Special case: Peek at root-menu; longpress again to close
+
+ // If we didn't already request a specialized update, when handling a menu action,
+ // then perform the usual fast update.
+ // FAST keeps things responsive: important because we're dealing with user input
+ if (!wantsToRender())
+ requestUpdate(Drivers::EInk::UpdateTypes::FAST);
+}
+
+// Dynamically create MenuItem entries for activating / deactivating Applets, for the "Applet Selection" submenu
+void InkHUD::MenuApplet::populateAppletPage()
+{
+ assert(items.size() == 0);
+
+ for (uint8_t i = 0; i < windowManager->getAppletCount(); i++) {
+ const char *name = windowManager->getAppletName(i);
+ bool *isActive = &(settings.userApplets.active[i]);
+ items.push_back(MenuItem(name, MenuAction::TOGGLE_APPLET, MenuPage::APPLETS, isActive));
+ }
+}
+
+// Dynamically create MenuItem entries for selecting which applets will automatically come to foreground when they have new data
+// We only populate this menu page with applets which are actually active
+// We use the MenuItem::checkState pointer to toggle the setting in MenuApplet::execute. Bit of a hack, but convenient.
+void InkHUD::MenuApplet::populateAutoshowPage()
+{
+ assert(items.size() == 0);
+
+ for (uint8_t i = 0; i < windowManager->getAppletCount(); i++) {
+ // Only add a menu item if applet is active
+ if (settings.userApplets.active[i]) {
+ const char *name = windowManager->getAppletName(i);
+ bool *isActive = &(settings.userApplets.autoshow[i]);
+ items.push_back(MenuItem(name, MenuAction::TOGGLE_AUTOSHOW_APPLET, MenuPage::AUTOSHOW, isActive));
+ }
+ }
+}
+
+void InkHUD::MenuApplet::populateRecentsPage()
+{
+ // How many values are shown for use to choose from
+ constexpr uint8_t optionCount = sizeof(RECENTS_OPTIONS_MINUTES) / sizeof(RECENTS_OPTIONS_MINUTES[0]);
+
+ // Create an entry for each item in RECENTS_OPTIONS_MINUTES array
+ // (Defined at top of this file)
+ for (uint8_t i = 0; i < optionCount; i++) {
+ std::string label = to_string(RECENTS_OPTIONS_MINUTES[i]) + " mins";
+ items.push_back(MenuItem(label.c_str(), MenuAction::SET_RECENTS, MenuPage::EXIT));
+ }
+}
+
+// Renders the panel shown at the top of the root menu.
+// Displays the clock, and several other pieces of instantaneous system info,
+// which we'd prefer not to have displayed in a normal applet, as they update too frequently.
+void InkHUD::MenuApplet::drawSystemInfoPanel(int16_t left, int16_t top, uint16_t width, uint16_t *renderedHeight)
+{
+ // Reset the height
+ // We'll add to this as we add elements
+ uint16_t height = 0;
+
+ // Clock (potentially)
+ // ====================
+ std::string clockString = getTimeString();
+ if (clockString.length() > 0) {
+ setFont(fontLarge);
+ printAt(width / 2, top, clockString, CENTER, TOP);
+
+ height += fontLarge.lineHeight();
+ height += fontLarge.lineHeight() * 0.1; // Padding below clock
+ }
+
+ // Stats
+ // ===================
+
+ setFont(fontSmall);
+
+ // Position of the label row for the system info
+ const int16_t labelT = top + height;
+ height += fontSmall.lineHeight() * 1.1; // Slightly increased spacing
+
+ // Position of the data row for the system info
+ const int16_t valT = top + height;
+ height += fontSmall.lineHeight() * 1.1; // Slightly increased spacing (between bottom line and divider)
+
+ // Position of divider between the info panel and the menu entries
+ const int16_t divY = top + height;
+ height += fontSmall.lineHeight() * 0.2; // Padding *below* the divider. (Above first menu item)
+
+ // Create a variable number of columns
+ // Either 3 or 4, depending on whether we have GPS
+ // Todo
+ constexpr uint8_t N_COL = 3;
+ int16_t colL[N_COL];
+ int16_t colC[N_COL];
+ int16_t colR[N_COL];
+ for (uint8_t i = 0; i < N_COL; i++) {
+ colL[i] = left + ((width / N_COL) * i);
+ colC[i] = colL[i] + ((width / N_COL) / 2);
+ colR[i] = colL[i] + (width / N_COL);
+ }
+
+ // Info blocks, left to right
+
+ // Voltage
+ float voltage = powerStatus->getBatteryVoltageMv() / 1000.0;
+ char voltageStr[6]; // "XX.XV"
+ sprintf(voltageStr, "%.1fV", voltage);
+ printAt(colC[0], labelT, "Bat", CENTER, TOP);
+ printAt(colC[0], valT, voltageStr, CENTER, TOP);
+
+ // Divider
+ for (int16_t y = valT; y <= divY; y += 3)
+ drawPixel(colR[0], y, BLACK);
+
+ // Channel Util
+ char chUtilStr[4]; // "XX%"
+ sprintf(chUtilStr, "%2.f%%", airTime->channelUtilizationPercent());
+ printAt(colC[1], labelT, "Ch", CENTER, TOP);
+ printAt(colC[1], valT, chUtilStr, CENTER, TOP);
+
+ // Divider
+ for (int16_t y = valT; y <= divY; y += 3)
+ drawPixel(colR[1], y, BLACK);
+
+ // Duty Cycle (AirTimeTx)
+ char dutyUtilStr[4]; // "XX%"
+ sprintf(dutyUtilStr, "%2.f%%", airTime->utilizationTXPercent());
+ printAt(colC[2], labelT, "Duty", CENTER, TOP);
+ printAt(colC[2], valT, dutyUtilStr, CENTER, TOP);
+
+ /*
+ // Divider
+ for (int16_t y = valT; y <= divY; y += 3)
+ drawPixel(colR[2], y, BLACK);
+
+ // GPS satellites - todo
+ printAt(colC[3], labelT, "Sats", CENTER, TOP);
+ printAt(colC[3], valT, "ToDo", CENTER, TOP);
+ */
+
+ // Horizontal divider, at bottom of system info panel
+ for (int16_t x = 0; x < width; x += 2) // Divider, centered in the padding between first system panel and first item
+ drawPixel(x, divY, BLACK);
+
+ if (renderedHeight != nullptr)
+ *renderedHeight = height;
+}
+
+// Get the height of the the panel drawn at the top of the menu
+// This is inefficient, as we do actually have to render the panel to determine the height
+// It solves a catch-22 situtation, where slotCount needs to know panel height, and panel height needs to know slotCount
+uint16_t InkHUD::MenuApplet::getSystemInfoPanelHeight()
+{
+ // Render *waay* off screen
+ uint16_t height = 0;
+ drawSystemInfoPanel(INT16_MIN, INT16_MIN, 1, &height);
+
+ return height;
+}
+
+#endif
\ No newline at end of file
diff --git a/src/graphics/niche/InkHUD/Applets/System/Menu/MenuApplet.h b/src/graphics/niche/InkHUD/Applets/System/Menu/MenuApplet.h
new file mode 100644
index 000000000..f2e9b3947
--- /dev/null
+++ b/src/graphics/niche/InkHUD/Applets/System/Menu/MenuApplet.h
@@ -0,0 +1,60 @@
+#ifdef MESHTASTIC_INCLUDE_INKHUD
+
+#include "configuration.h"
+
+#include "graphics/niche/Drivers/Backlight/LatchingBacklight.h"
+#include "graphics/niche/InkHUD/Applet.h"
+#include "graphics/niche/InkHUD/WindowManager.h"
+
+#include "./MenuItem.h"
+#include "./MenuPage.h"
+
+#include "concurrency/OSThread.h"
+
+namespace NicheGraphics::InkHUD
+{
+
+class Applet;
+
+class MenuApplet : public Applet, public concurrency::OSThread
+{
+ public:
+ MenuApplet();
+ void onActivate() override;
+ void onForeground() override;
+ void onBackground() override;
+ void onButtonShortPress() override;
+ void onButtonLongPress() override;
+ void onRender() override;
+
+ void show(Tile *t); // Open the menu, onto a user tile
+
+ protected:
+ int32_t runOnce() override;
+
+ void execute(MenuItem item); // Perform the MenuAction associated with a MenuItem, if any
+ void showPage(MenuPage page); // Load and display a MenuPage
+ void populateAppletPage(); // Dynamically create MenuItems for toggling loaded applets
+ void populateAutoshowPage(); // Dynamically create MenuItems for selecting which applets can autoshow
+ void populateRecentsPage(); // Create menu items: a choice of values for settings.recentlyActiveSeconds
+ uint16_t getSystemInfoPanelHeight();
+ void drawSystemInfoPanel(int16_t left, int16_t top, uint16_t width,
+ uint16_t *height = nullptr); // Info panel at top of root menu
+
+ MenuPage currentPage;
+ uint8_t cursor = 0; // Which menu item is currently highlighted
+ bool cursorShown = false; // Is *any* item highlighted? (Root menu: no initial selection)
+
+ uint16_t systemInfoPanelHeight = 0; // Need to know before we render
+
+ std::vector